Example #1
0
    def extract_slice(self, data='strain', phi=None, az_idx=None, z_idx=None):
        """ Extract 2D data slice wrt. azimuthal slice index or angle (phi).

        The extracted data is defined using the data variable (str), which
        must be one of the following: peaks, peaks error, fwhm, fwhm error,
        strain, strain error, shear strain, stress, shear stress.

        Certain combinations of data type and azimuthal index/phi will not
        work (e.g. can't extract peaks wrt. phi only wrt. az. index).

        Note: must define EITHER phi or az_idx

        Args:
            data (str): Data type to extract (see above)
            phi (float): Azimuthal angle in rad
            az_idx (int): Azimuthal slice index
            z_idx (int): Index of slice height in 3D array
        """
        complex_check(data, self.analysis_state, phi, az_idx)
        command = text_cleaning(data)
        az_command = 'phi' if phi is not None else 'az_idx'

        if az_command == 'az_idx':
            az_idx = int(az_idx)
            if 'stress' not in command:
                data_command = {
                    'peaks': self.peaks,
                    'peaks error': self.peaks_err,
                    'fwhm': self.fwhm,
                    'fwhm error': self.fwhm_err,
                    'strain': self.strain,
                    'strain error': self.strain_err
                }

                data = data_command[command][..., az_idx]
            else:
                d = self.strain if 'err' not in command else self.strain_err
                e_xx, e_yy = d[..., az_idx], d[..., az90(self.phi, az_idx)]
                data = self.stress_eqn(e_xx, e_yy, self.E, self.v)

        else:
            tensor = self.strain_tensor
            tensor = tensor[..., 0], tensor[..., 1], tensor[..., 2]
            shear = True if 'shear' in command else False
            stress = True if 'stress' in command else False

            if shear:
                e_xy = shear_transformation(phi, *tensor)
                data = self.G * e_xy if stress else e_xy

            elif stress:
                e_xx = strain_transformation(phi, *tensor)
                e_yy = strain_transformation(phi + np.pi / 2, *tensor)
                data = self.stress_eqn(e_xx, e_yy, self.E, self.v)

            else:
                data = strain_transformation(phi, *tensor)
        data = data[z_idx] if z_idx is not None else data
        return data
Example #2
0
    def extract_slice(self, data='strain', phi=None, az_idx=None, z_idx=None):
        """ Extract 2D data slice wrt. azimuthal slice index or angle (phi).

        The extracted data is defined using the data variable (str), which
        must be one of the following: peaks, peaks error, fwhm, fwhm error,
        strain, strain error, shear strain, stress, shear stress.

        Certain combinations of data type and azimuthal index/phi will not
        work (e.g. can't extract peaks wrt. phi only wrt. az. index).

        Note: must define EITHER phi or az_idx

        Args:
            data (str): Data type to extract (see above)
            phi (float): Azimuthal angle in rad
            az_idx (int): Azimuthal slice index
            z_idx (int): Index of slice height in 3D array
        """
        complex_check(data, self.analysis_state, phi, az_idx)
        command = text_cleaning(data)
        az_command = 'phi' if phi is not None else 'az_idx'

        if az_command == 'az_idx':
            az_idx = int(az_idx)
            if 'stress' not in command:
                data_command = {'peaks': self.peaks,
                                'peaks error': self.peaks_err,
                                'fwhm': self.fwhm,
                                'fwhm error': self.fwhm_err,
                                'strain': self.strain,
                                'strain error': self.strain_err}

                data = data_command[command][..., az_idx]
            else:
                d = self.strain if 'err' not in command else self.strain_err
                e_xx, e_yy = d[..., az_idx], d[..., az90(self.phi, az_idx)]
                data = self.stress_eqn(e_xx, e_yy, self.E, self.v)

        else:
            tensor = self.strain_tensor
            tensor = tensor[..., 0], tensor[..., 1], tensor[..., 2]
            shear = True if 'shear' in command else False
            stress = True if 'stress' in command else False

            if shear:
                e_xy = shear_transformation(phi, *tensor)
                data = self.G * e_xy if stress else e_xy

            elif stress:
                e_xx = strain_transformation(phi, *tensor)
                e_yy = strain_transformation(phi + np.pi / 2, *tensor)
                data = self.stress_eqn(e_xx, e_yy, self.E, self.v)

            else:
                data = strain_transformation(phi, *tensor)
        data = data[z_idx] if z_idx is not None else data
        return data
Example #3
0
 def test_angles(self):
     self.data.calculate_strain(self.q0)
     # Compare angles, same position
     for p_idx in [0, 7, 12, 26, 32]:
         tensor = e_xx[p_idx], e_yy[p_idx], e_xy[p_idx]
         initial = strain_transformation(self.data.phi, *tensor)
         processed = self.data.strain[p_idx]
         max_diff = np.abs(np.max(initial - processed))
         assert max_diff < 10**-4, (p_idx, max_diff)  # Brittle (linux)?!
Example #4
0
 def test_angles(self):
     self.data.calculate_strain(self.q0)
     # Compare angles, same position
     for p_idx in [0, 7, 12, 26, 32]:
         tensor = e_xx[p_idx], e_yy[p_idx], e_xy[p_idx]
         initial = strain_transformation(self.data.phi, *tensor)
         processed = self.data.strain[p_idx]
         max_diff = np.abs(np.max(initial - processed))
         assert max_diff < 10**-4, (p_idx, max_diff)  # Brittle (linux)?!
Example #5
0
 def test_angles(self):
     self.data.calculate_strain(self.q0)
     # Compare angles, same position
     for p_idx in [(0, 0), (4, 4), (3, 5), (1, 2), (0, 4)]:
         tensor = e_xx[p_idx], e_yy[p_idx], e_xy[p_idx]
         initial = strain_transformation(self.data.phi, *tensor)
         processed = self.data.strain[p_idx]
         max_diff = np.abs(np.max(initial - processed))
         assert max_diff < 10**-4, (p_idx, max_diff)
Example #6
0
 def test_angles(self):
     self.data.calculate_strain(self.q0)
     # Compare angles, same position
     for p_idx in [(0, 0), (4, 4), (3, 5), (1, 2), (0, 4)]:
         tensor = e_xx[p_idx], e_yy[p_idx], e_xy[p_idx]
         initial = strain_transformation(self.data.phi, *tensor)
         processed = self.data.strain[p_idx]
         max_diff = np.abs(np.max(initial - processed))
         assert max_diff < 10 ** -4, (p_idx, max_diff)
Example #7
0
 def test_positions(self):
     self.data.calculate_strain(self.q0)
     # Compare positions, same angle
     for idx in [0, 7, 12, 26, 32]:
         tensor = e_xx, e_yy, e_xy
         initial = strain_transformation(self.data.phi[idx], *tensor)
         processed_1 = self.data.strain[..., idx]
         processed_2 = self.data.extract_slice(phi=self.data.phi[idx])
         for processed in [processed_1, processed_2]:
             max_diff = np.abs(np.max(initial - processed))
             assert max_diff < 10**-4, (idx, max_diff)  # Brittle (linux)?!
Example #8
0
 def test_positions(self):
     self.data.calculate_strain(self.q0)
     # Compare positions, same angle
     for idx in [0, 7, 12, 26, 32]:
         tensor = e_xx, e_yy, e_xy
         initial = strain_transformation(self.data.phi[idx], *tensor)
         processed_1 = self.data.strain[..., idx]
         processed_2 = self.data.extract_slice(phi=self.data.phi[idx])
         for processed in [processed_1, processed_2]:
             max_diff = np.abs(np.max(initial - processed))
             assert max_diff < 10**-4, (idx, max_diff)  # Brittle (linux)?!
Example #9
0
    def extract_strain_array(self, phi):
        """
        Add valus for phi
        :param phi:
        :return:
        """
        strain = np.nan * np.ones((self.x.shape + (1, ) + phi.shape))

        for idx, tt in enumerate(phi):
            e_xx1 = strain_transformation(tt, self.e_xx, self.e_yy, self.e_xy)
            strain[:, :, 0, idx] = e_xx1

        return strain
Example #10
0
    def extract_strain_array(self, phi):
        """
        Add valus for phi
        :param phi:
        :return:
        """
        strain = np.nan * np.ones((self.x.shape + (1,) + phi.shape))

        for idx, tt in enumerate(phi):
            e_xx1 = strain_transformation(tt, self.e_xx, self.e_yy, self.e_xy)
            strain[:, :, 0, idx] = e_xx1

        return strain
Example #11
0
    def plot_strain_fit(self, pnt=None, figsize=(11, 5)):
        """ Plots fitted in-plane strain field and tensor for given data point.

        Plots strain wrt. phi and associated tensor fit. The tensor fit is
        represented as a Mohr's circle, with e_xx, e_yy (for that point) being
        highlighted on both plots.

        Args:
            pnt (tuple): Define data point (index) else point (0, ) x ndim.
            figsize (tuple): Figure size
        """
        pnt = (0,) * (self.strain.ndim - 1) if pnt is None else pnt

        fig, (ax_1, ax_2) = plt.subplots(1, 2, figsize=figsize)

        p = self.strain_tensor[pnt]
        ax_1.plot(self.phi, self.strain[pnt], 'k*')
        phi_2 = np.linspace(self.phi[0], self.phi[-1], 1000)
        ax_1.plot(phi_2, strain_transformation(phi_2, *p), 'k-', linewidth=0.5)
        ax_1.set_xlabel(r'$\phi$ (rad)', size=14)
        ax_1.set_ylabel(r'$\epsilon$', size=14)
        ax_1.ticklabel_format(axis='both', style='sci', scilimits=(-3, 3))

        ax_2.ticklabel_format(axis='both', style='sci', scilimits=(-3, 3))
        ax_2.set_xlabel(r'$\epsilon$', size=14)
        ax_2.set_ylabel(r'$\gamma}$', size=14)

        e_xx, e_yy, e_xy = self.strain_tensor[pnt]
        mean = (e_xx + e_yy) / 2
        e_1 = mean + (e_xy**2 + ((e_xx - e_yy) / 2)**2)**0.5
        e_2 = e_xx + e_yy - e_1
        radius = (e_1 - e_2) / 2

        for x, text in zip([self.phi[0], self.phi[0] + np.pi/2],
                           [r'$\epsilon_{xx}$', r'$\epsilon_{yy}$']):
            ax_1.axvline(x, ymax=0.93, linewidth=0.5, ls='--', color='k')
            y = ax_1.get_ylim()[1] * 0.96
            ax_1.text(x, y, text, ha='center', va='bottom')

        circ = plt.Circle((mean, 0), radius=radius, color='k', fill=False)
        ax_2.add_patch(circ)
        for x, y, text in zip([e_1, e_2, e_xx, e_yy],
                              [0, 0, e_xy, -e_xy],
                              [r'$\epsilon_{1}$', r'$\epsilon_{2}$',
                               r'$(\epsilon_{xx}$, $\epsilon_{xy})$',
                               r'$(\epsilon_{yy}$, $\epsilon_{yx})$']):
            ax_2.plot(x, y, 'k.')
            ax_2.annotate('  %s' % text, xy=(x, y),  xytext=(x, y), ha='left')
        ax_2.plot([e_xx, e_yy], [e_xy, -e_xy], 'k--', linewidth=0.5)
        fig.tight_layout()
Example #12
0
    def plot_strain_fit(self, pnt=None, figsize=(11, 5)):
        """ Plots fitted in-plane strain field and tensor for given data point.

        Plots strain wrt. phi and associated tensor fit. The tensor fit is
        represented as a Mohr's circle, with e_xx, e_yy (for that point) being
        highlighted on both plots.

        Args:
            pnt (tuple): Define data point (index) else point (0, ) x ndim.
            figsize (tuple): Figure size
        """
        pnt = (0, ) * (self.strain.ndim - 1) if pnt is None else pnt

        fig, (ax_1, ax_2) = plt.subplots(1, 2, figsize=figsize)

        p = self.strain_tensor[pnt]
        ax_1.plot(self.phi, self.strain[pnt], 'k*')
        phi_2 = np.linspace(self.phi[0], self.phi[-1], 1000)
        ax_1.plot(phi_2, strain_transformation(phi_2, *p), 'k-', linewidth=0.5)
        ax_1.set_xlabel(r'$\phi$ (rad)', size=14)
        ax_1.set_ylabel(r'$\epsilon$', size=14)
        ax_1.ticklabel_format(axis='both', style='sci', scilimits=(-3, 3))

        ax_2.ticklabel_format(axis='both', style='sci', scilimits=(-3, 3))
        ax_2.set_xlabel(r'$\epsilon$', size=14)
        ax_2.set_ylabel(r'$\gamma}$', size=14)

        e_xx, e_yy, e_xy = self.strain_tensor[pnt]
        mean = (e_xx + e_yy) / 2
        e_1 = mean + (e_xy**2 + ((e_xx - e_yy) / 2)**2)**0.5
        e_2 = e_xx + e_yy - e_1
        radius = (e_1 - e_2) / 2

        for x, text in zip([self.phi[0], self.phi[0] + np.pi / 2],
                           [r'$\epsilon_{xx}$', r'$\epsilon_{yy}$']):
            ax_1.axvline(x, ymax=0.93, linewidth=0.5, ls='--', color='k')
            y = ax_1.get_ylim()[1] * 0.96
            ax_1.text(x, y, text, ha='center', va='bottom')

        circ = plt.Circle((mean, 0), radius=radius, color='k', fill=False)
        ax_2.add_patch(circ)
        for x, y, text in zip([e_1, e_2, e_xx, e_yy], [0, 0, e_xy, -e_xy], [
                r'$\epsilon_{1}$', r'$\epsilon_{2}$',
                r'$(\epsilon_{xx}$, $\epsilon_{xy})$',
                r'$(\epsilon_{yy}$, $\epsilon_{yx})$'
        ]):
            ax_2.plot(x, y, 'k.')
            ax_2.annotate('  %s' % text, xy=(x, y), xytext=(x, y), ha='left')
        ax_2.plot([e_xx, e_yy], [e_xy, -e_xy], 'k--', linewidth=0.5)
        fig.tight_layout()