Exemplo n.º 1
0
    def from_stress_dict(cls, stress_dict, tol=0.1, vasp=True):
        """
        Constructs the elastic tensor from IndependentStrain-Stress dictionary
        corresponding to legacy behavior of elasticity package.

        Args:
            stress_dict (dict): dictionary of stresses indexed by corresponding
                IndependentStrain objects.
        """
        inds = [(0, 0), (1, 1), (2, 2), (1, 2), (0, 2), (0, 1)]
        c_ij = np.array([[
            np.polyfit([
                strain[ind1] for strain in list(stress_dict.keys())
                if (strain.i, strain.j) == ind1
            ], [
                stress_dict[strain][ind2]
                for strain in list(stress_dict.keys())
                if (strain.i, strain.j) == ind1
            ], 1)[0] for ind1 in inds
        ] for ind2 in inds])
        if vasp:
            c_ij *= -0.1  # Convert units/sign convention of vasp stress tensor
        c_ij[0:,
             3:] = 0.5 * c_ij[0:, 3:]  # account for voigt doubling of e4,e5,e6
        c_ij = SQTensor(c_ij)
        c_ij = c_ij.zeroed(tol)
        return cls(c_ij)
Exemplo n.º 2
0
    def __new__(cls, strain_matrix, dfm=None):
        """
        Create a Strain object.  Note that the constructor uses __new__
        rather than __init__ according to the standard method of
        subclassing numpy ndarrays.  Note also that the default constructor
        does not include the deformation gradient

        Args:
            strain_matrix (3x3 array-like): the 3x3 array-like
                representing the Green-Lagrange strain
        """

        obj = SQTensor(strain_matrix).view(cls)
        obj._dfm = dfm
        if not obj.is_symmetric():
            raise ValueError("Strain objects must be initialized "
                             "with a symmetric array-like.")

        if dfm is None:
            warnings.warn("Constructing a strain object without a deformation "
                          "matrix makes many methods unusable.  Use "
                          "Strain.from_deformation to construct a Strain object"
                          " from a deformation gradient.")
        elif (np.array(dfm) - obj < 1e-5).all():
            warnings.warn("Warning: deformation matrix does not correspond "
                          "to input strain_matrix value")
        return obj
Exemplo n.º 3
0
    def __new__(cls, strain_matrix, dfm=None):
        """
        Create a Strain object.  Note that the constructor uses __new__
        rather than __init__ according to the standard method of
        subclassing numpy ndarrays.  Note also that the default constructor
        does not include the deformation gradient

        Args:
            strain_matrix (3x3 array-like): the 3x3 array-like
                representing the Green-Lagrange strain
        """

        obj = SQTensor(strain_matrix).view(cls)
        obj._dfm = dfm
        if not obj.is_symmetric():
            raise ValueError("Strain objects must be initialized "
                             "with a symmetric array-like.")

        if dfm is None:
            warnings.warn(
                "Constructing a strain object without a deformation "
                "matrix makes many methods unusable.  Use "
                "Strain.from_deformation to construct a Strain object"
                " from a deformation gradient.")
        elif (np.array(dfm) - obj < 1e-5).all():
            warnings.warn("Warning: deformation matrix does not correspond "
                          "to input strain_matrix value")
        return obj
Exemplo n.º 4
0
 def test_zeroed(self):
     self.assertArrayEqual(self.low_val.zeroed(),
                           SQTensor([[0, 1 + 1e-5, 0],
                                     [1 + 1e-6, 0, 0],
                                     [0, 0, 1 + 1e-5]]))
     self.assertArrayEqual(self.low_val.zeroed(tol=1e-6),
                           SQTensor([[1e-6, 1 + 1e-5, 1e-6],
                                     [1 + 1e-6, 1e-6, 1e-6],
                                     [0, 0, 1 + 1e-5]]))
Exemplo n.º 5
0
 def test_rotate(self):
     self.assertArrayAlmostEqual(self.non_symm.rotate(self.rotation),
                                 SQTensor([[0.531, 0.485, 0.271],
                                           [0.700, 0.5, 0.172],
                                           [0.171, 0.233, 0.068]]),
                                 decimal=3)
     self.assertRaises(ValueError, self.non_symm.rotate, self.symm_sqtensor)
Exemplo n.º 6
0
    def test_properties(self):
        # transpose
        self.assertArrayEqual(self.non_symm.trans, SQTensor([[0.1, 0.4, 0.2],
                                                         [0.2, 0.5, 0.5],
                                                         [0.3, 0.6, 0.5]]))
        self.assertArrayEqual(self.rand_sqtensor.trans,
                              np.transpose(self.rand_sqtensor))
        self.assertArrayEqual(self.symm_sqtensor,
                              self.symm_sqtensor.trans)
        # inverse
        self.assertArrayEqual(self.non_symm.inv,
                              np.linalg.inv(self.non_symm))
        with self.assertRaises(ValueError):
            self.non_invertible.inv

        # determinant
        self.assertEqual(self.rand_sqtensor.det,
                         np.linalg.det(self.rand_sqtensor))
        self.assertEqual(self.non_invertible.det,
                         0.0)
        self.assertEqual(self.non_symm.det, 0.009)

        # symmetrized
        self.assertArrayEqual(self.rand_sqtensor.symmetrized,
                              0.5 * (self.rand_sqtensor + self.rand_sqtensor.trans))
        self.assertArrayEqual(self.symm_sqtensor,
                              self.symm_sqtensor.symmetrized)
        self.assertArrayAlmostEqual(self.non_symm.symmetrized,
                                    SQTensor([[0.1, 0.3, 0.25],
                                              [0.3, 0.5, 0.55],
                                              [0.25, 0.55, 0.5]]))

        # invariants
        i1 = np.trace(self.rand_sqtensor)
        i2 = self.rand_sqtensor[0, 0] * self.rand_sqtensor[1, 1] + \
             self.rand_sqtensor[1, 1] * self.rand_sqtensor[2, 2] + \
             self.rand_sqtensor[2, 2] * self.rand_sqtensor[0, 0] - \
             self.rand_sqtensor[0, 1] * self.rand_sqtensor[1, 0] - \
             self.rand_sqtensor[0, 2] * self.rand_sqtensor[2, 0] - \
             self.rand_sqtensor[2, 1] * self.rand_sqtensor[1, 2]
        i3 = np.linalg.det(self.rand_sqtensor)
        self.assertArrayAlmostEqual([i1, i2, i3],
                                    self.rand_sqtensor.principal_invariants)
Exemplo n.º 7
0
    def piola_kirchoff_1(self, def_grad):
        """
        calculates the first Piola-Kirchoff stress

        Args:
            def_gradient (3x3 array-like): deformation gradient tensor
        """
        if not self.is_symmetric:
            raise ValueError("The stress tensor is not symmetric, \
                             PK stress is based on a symmetric stress tensor.")
        def_grad = SQTensor(def_grad)
        return def_grad.det*np.dot(self, def_grad.inv.trans)
Exemplo n.º 8
0
    def __new__(cls, stress_matrix):
        """
        Create a Stress object.  Note that the constructor uses __new__
        rather than __init__ according to the standard method of
        subclassing numpy ndarrays.

        Args:
            stress_matrix (3x3 array-like): the 3x3 array-like
                representing the stress
        """
        obj = SQTensor(stress_matrix).view(cls)
        return obj
Exemplo n.º 9
0
    def __new__(cls, deformation_gradient):
        """
        Create a Deformation object.  Note that the constructor uses __new__
        rather than __init__ according to the standard method of subclassing
        numpy ndarrays.

        Args:
            deformation_gradient (3x3 array-like): the 3x3 array-like
                representing the deformation gradient
        """

        obj = SQTensor(deformation_gradient).view(cls)
        return obj
Exemplo n.º 10
0
    def __new__(cls, input_matrix):
        """
        Create an ElasticTensor object.  The constructor throws an error if
        the shape of the input_matrix argument is not 6x6, i. e. in Voigt-
        notation.  Also issues a warning if the input_matrix argument is
        not symmetric.  Note that the constructor uses __new__ rather than
        __init__ according to the standard method of subclassing numpy
        ndarrays.

        Args:
            input_matrix (6x6 array-like): the Voigt-notation 6x6 array-like
                representing the elastic tensor
        """
        obj = SQTensor(input_matrix).view(cls)
        if obj.shape != (6, 6):
            raise ValueError("Default elastic tensor constructor requires "
                             "input argument to be the Voigt-notation 6x6 "
                             "array.  To construct from a 3x3x3x3 array, use "
                             "ElasticTensor.from_full_tensor")
        if not obj.is_symmetric():
            warnings.warn("Elastic tensor input is not symmetric!")
        return obj
Exemplo n.º 11
0
    def __new__(cls, input_matrix):
        """
        Create an ElasticTensor object.  The constructor throws an error if
        the shape of the input_matrix argument is not 6x6, i. e. in Voigt-
        notation.  Also issues a warning if the input_matrix argument is
        not symmetric.  Note that the constructor uses __new__ rather than
        __init__ according to the standard method of subclassing numpy
        ndarrays.

        Args:
            input_matrix (6x6 array-like): the Voigt-notation 6x6 array-like
                representing the elastic tensor
        """
        obj = SQTensor(input_matrix).view(cls)
        if obj.shape != (6, 6):
            raise ValueError("Default elastic tensor constructor requires "
                             "input argument to be the Voigt-notation 6x6 "
                             "array.  To construct from a 3x3x3x3 array, use "
                             "ElasticTensor.from_full_tensor")
        if not obj.is_symmetric():
            warnings.warn("Elastic tensor input is not symmetric!")
        return obj
Exemplo n.º 12
0
    def from_stress_dict(cls, stress_dict, tol=0.1, vasp=True):
        """
        Constructs the elastic tensor from IndependentStrain-Stress dictionary
        corresponding to legacy behavior of elasticity package.

        Args:
            stress_dict (dict): dictionary of stresses indexed by corresponding
                IndependentStrain objects.
        """
        inds = [(0, 0), (1, 1), (2, 2), (1, 2), (0, 2), (0, 1)]
        c_ij = np.array([[np.polyfit([strain[ind1] for strain in list(stress_dict.keys())
                                      if (strain.i, strain.j) == ind1],
                                     [stress_dict[strain][ind2] for strain
                                      in list(stress_dict.keys())
                                      if (strain.i, strain.j) == ind1], 1)[0]
                          for ind1 in inds] for ind2 in inds])
        if vasp:
            c_ij *= -0.1  # Convert units/sign convention of vasp stress tensor
        c_ij[0:, 3:] = 0.5 * c_ij[0:, 3:]  # account for voigt doubling of e4,e5,e6
        c_ij = SQTensor(c_ij)
        c_ij = c_ij.zeroed(tol)
        return cls(c_ij)
Exemplo n.º 13
0
    def piola_kirchoff_2(self, def_grad):
        """
        calculates the second Piola-Kirchoff stress

        Args:
            f (3x3 array-like): rate of deformation tensor
        """

        def_grad = SQTensor(def_grad)
        if not self.is_symmetric:
            raise ValueError("The stress tensor is not symmetric, \
                             PK stress is based on a symmetric stress tensor.")
        return def_grad.det*np.dot(np.dot(def_grad.inv, self),
                                   def_grad.inv.trans)
Exemplo n.º 14
0
    def setUp(self):
        self.rand_sqtensor = SQTensor(np.random.randn(3, 3))
        self.symm_sqtensor = SQTensor([[0.1, 0.3, 0.4],
                                       [0.3, 0.5, 0.2],
                                       [0.4, 0.2, 0.6]])
        self.non_invertible = SQTensor([[0.1, 0, 0],
                                        [0.2, 0, 0],
                                        [0, 0, 0]])
        self.non_symm = SQTensor([[0.1, 0.2, 0.3],
                                  [0.4, 0.5, 0.6],
                                  [0.2, 0.5, 0.5]])
        self.low_val = SQTensor([[1e-6, 1 + 1e-5, 1e-6],
                                 [1 + 1e-6, 1e-6, 1e-6],
                                 [1e-7, 1e-7, 1 + 1e-5]])
        self.low_val_2 = SQTensor([[1e-6, -1 - 1e-6, 1e-6],
                                   [1 + 1e-7, 1e-6, 1e-6],
                                   [1e-7, 1e-7, 1 + 1e-6]])

        a = 3.14 * 42.5 / 180
        self.rotation = SQTensor([[math.cos(a), 0, math.sin(a)],
                                  [0, 1, 0],
                                  [-math.sin(a), 0, math.cos(a)]])
Exemplo n.º 15
0
 def test_get_scaled(self):
     self.assertArrayEqual(self.non_symm.get_scaled(10.),
                           SQTensor([[1, 2, 3], [4, 5, 6], [2, 5, 5]]))
Exemplo n.º 16
0
class SQTensorTest(PymatgenTest):
    def setUp(self):
        self.rand_sqtensor = SQTensor(np.random.randn(3, 3))
        self.symm_sqtensor = SQTensor([[0.1, 0.3, 0.4],
                                       [0.3, 0.5, 0.2],
                                       [0.4, 0.2, 0.6]])
        self.non_invertible = SQTensor([[0.1, 0, 0],
                                        [0.2, 0, 0],
                                        [0, 0, 0]])
        self.non_symm = SQTensor([[0.1, 0.2, 0.3],
                                  [0.4, 0.5, 0.6],
                                  [0.2, 0.5, 0.5]])
        self.low_val = SQTensor([[1e-6, 1 + 1e-5, 1e-6],
                                 [1 + 1e-6, 1e-6, 1e-6],
                                 [1e-7, 1e-7, 1 + 1e-5]])
        self.low_val_2 = SQTensor([[1e-6, -1 - 1e-6, 1e-6],
                                   [1 + 1e-7, 1e-6, 1e-6],
                                   [1e-7, 1e-7, 1 + 1e-6]])

        a = 3.14 * 42.5 / 180
        self.rotation = SQTensor([[math.cos(a), 0, math.sin(a)],
                                  [0, 1, 0],
                                  [-math.sin(a), 0, math.cos(a)]])

    def test_new(self):
        non_sq_matrix = [[0.1, 0.2, 0.1],
                         [0.1, 0.2, 0.3],
                         [0.1, 0.2, 0.3],
                         [0.1, 0.1, 0.1]]
        bad_matrix = [[0.1, 0.2],
                      [0.2, 0.3, 0.4],
                      [0.2, 0.3, 0.5]]
        self.assertRaises(ValueError, SQTensor, non_sq_matrix)
        self.assertRaises(ValueError, SQTensor, bad_matrix)

    def test_properties(self):
        # transpose
        self.assertArrayEqual(self.non_symm.trans, SQTensor([[0.1, 0.4, 0.2],
                                                         [0.2, 0.5, 0.5],
                                                         [0.3, 0.6, 0.5]]))
        self.assertArrayEqual(self.rand_sqtensor.trans,
                              np.transpose(self.rand_sqtensor))
        self.assertArrayEqual(self.symm_sqtensor,
                              self.symm_sqtensor.trans)
        # inverse
        self.assertArrayEqual(self.non_symm.inv,
                              np.linalg.inv(self.non_symm))
        with self.assertRaises(ValueError):
            self.non_invertible.inv

        # determinant
        self.assertEqual(self.rand_sqtensor.det,
                         np.linalg.det(self.rand_sqtensor))
        self.assertEqual(self.non_invertible.det,
                         0.0)
        self.assertEqual(self.non_symm.det, 0.009)

        # symmetrized
        self.assertArrayEqual(self.rand_sqtensor.symmetrized,
                              0.5 * (self.rand_sqtensor + self.rand_sqtensor.trans))
        self.assertArrayEqual(self.symm_sqtensor,
                              self.symm_sqtensor.symmetrized)
        self.assertArrayAlmostEqual(self.non_symm.symmetrized,
                                    SQTensor([[0.1, 0.3, 0.25],
                                              [0.3, 0.5, 0.55],
                                              [0.25, 0.55, 0.5]]))

        # invariants
        i1 = np.trace(self.rand_sqtensor)
        i2 = self.rand_sqtensor[0, 0] * self.rand_sqtensor[1, 1] + \
             self.rand_sqtensor[1, 1] * self.rand_sqtensor[2, 2] + \
             self.rand_sqtensor[2, 2] * self.rand_sqtensor[0, 0] - \
             self.rand_sqtensor[0, 1] * self.rand_sqtensor[1, 0] - \
             self.rand_sqtensor[0, 2] * self.rand_sqtensor[2, 0] - \
             self.rand_sqtensor[2, 1] * self.rand_sqtensor[1, 2]
        i3 = np.linalg.det(self.rand_sqtensor)
        self.assertArrayAlmostEqual([i1, i2, i3],
                                    self.rand_sqtensor.principal_invariants)

    def test_symmetry(self):
        self.assertTrue(self.symm_sqtensor.is_symmetric())
        self.assertFalse(self.non_symm.is_symmetric())
        self.assertTrue(self.low_val.is_symmetric())
        self.assertFalse(self.low_val.is_symmetric(tol=1e-8))

    def test_rotation(self):
        self.assertTrue(self.rotation.is_rotation())
        self.assertFalse(self.symm_sqtensor.is_rotation())
        self.assertTrue(self.low_val_2.is_rotation())
        self.assertFalse(self.low_val_2.is_rotation(tol=1e-8))

    def test_rotate(self):
        self.assertArrayAlmostEqual(self.non_symm.rotate(self.rotation),
                                    SQTensor([[0.531, 0.485, 0.271],
                                              [0.700, 0.5, 0.172],
                                              [0.171, 0.233, 0.068]]),
                                    decimal=3)
        self.assertRaises(ValueError, self.non_symm.rotate, self.symm_sqtensor)

    def test_get_scaled(self):
        self.assertArrayEqual(self.non_symm.get_scaled(10.),
                              SQTensor([[1, 2, 3], [4, 5, 6], [2, 5, 5]]))

    def test_polar_decomposition(self):
        u, p = self.rand_sqtensor.polar_decomposition()
        self.assertArrayAlmostEqual(np.dot(u, p), self.rand_sqtensor)
        self.assertArrayAlmostEqual(np.eye(3),
                                    np.dot(u, np.conjugate(np.transpose(u))))

    def test_zeroed(self):
        self.assertArrayEqual(self.low_val.zeroed(),
                              SQTensor([[0, 1 + 1e-5, 0],
                                        [1 + 1e-6, 0, 0],
                                        [0, 0, 1 + 1e-5]]))
        self.assertArrayEqual(self.low_val.zeroed(tol=1e-6),
                              SQTensor([[1e-6, 1 + 1e-5, 1e-6],
                                        [1 + 1e-6, 1e-6, 1e-6],
                                        [0, 0, 1 + 1e-5]]))
Exemplo n.º 17
0
    def setUp(self):
        self.rand_sqtensor = SQTensor(np.random.randn(3, 3))
        self.symm_sqtensor = SQTensor([[0.1, 0.3, 0.4], [0.3, 0.5, 0.2],
                                       [0.4, 0.2, 0.6]])
        self.non_invertible = SQTensor([[0.1, 0, 0], [0.2, 0, 0], [0, 0, 0]])
        self.non_symm = SQTensor([[0.1, 0.2, 0.3], [0.4, 0.5, 0.6],
                                  [0.2, 0.5, 0.5]])
        self.low_val = SQTensor([[1e-6, 1 + 1e-5,
                                  1e-6], [1 + 1e-6, 1e-6, 1e-6],
                                 [1e-7, 1e-7, 1 + 1e-5]])
        self.low_val_2 = SQTensor([[1e-6, -1 - 1e-6, 1e-6],
                                   [1 + 1e-7, 1e-6, 1e-6],
                                   [1e-7, 1e-7, 1 + 1e-6]])

        a = 3.14 * 42.5 / 180
        self.rotation = SQTensor([[math.cos(a), 0, math.sin(a)], [0, 1, 0],
                                  [-math.sin(a), 0,
                                   math.cos(a)]])
Exemplo n.º 18
0
class SQTensorTest(PymatgenTest):
    def setUp(self):
        self.rand_sqtensor = SQTensor(np.random.randn(3, 3))
        self.symm_sqtensor = SQTensor([[0.1, 0.3, 0.4], [0.3, 0.5, 0.2],
                                       [0.4, 0.2, 0.6]])
        self.non_invertible = SQTensor([[0.1, 0, 0], [0.2, 0, 0], [0, 0, 0]])
        self.non_symm = SQTensor([[0.1, 0.2, 0.3], [0.4, 0.5, 0.6],
                                  [0.2, 0.5, 0.5]])
        self.low_val = SQTensor([[1e-6, 1 + 1e-5,
                                  1e-6], [1 + 1e-6, 1e-6, 1e-6],
                                 [1e-7, 1e-7, 1 + 1e-5]])
        self.low_val_2 = SQTensor([[1e-6, -1 - 1e-6, 1e-6],
                                   [1 + 1e-7, 1e-6, 1e-6],
                                   [1e-7, 1e-7, 1 + 1e-6]])

        a = 3.14 * 42.5 / 180
        self.rotation = SQTensor([[math.cos(a), 0, math.sin(a)], [0, 1, 0],
                                  [-math.sin(a), 0,
                                   math.cos(a)]])

    def test_new(self):
        non_sq_matrix = [[0.1, 0.2, 0.1], [0.1, 0.2, 0.3], [0.1, 0.2, 0.3],
                         [0.1, 0.1, 0.1]]
        bad_matrix = [[0.1, 0.2], [0.2, 0.3, 0.4], [0.2, 0.3, 0.5]]
        self.assertRaises(ValueError, SQTensor, non_sq_matrix)
        self.assertRaises(ValueError, SQTensor, bad_matrix)

    def test_properties(self):
        # transpose
        self.assertArrayEqual(
            self.non_symm.trans,
            SQTensor([[0.1, 0.4, 0.2], [0.2, 0.5, 0.5], [0.3, 0.6, 0.5]]))
        self.assertArrayEqual(self.rand_sqtensor.trans,
                              np.transpose(self.rand_sqtensor))
        self.assertArrayEqual(self.symm_sqtensor, self.symm_sqtensor.trans)
        # inverse
        self.assertArrayEqual(self.non_symm.inv, np.linalg.inv(self.non_symm))
        with self.assertRaises(ValueError):
            self.non_invertible.inv

        # determinant
        self.assertEqual(self.rand_sqtensor.det,
                         np.linalg.det(self.rand_sqtensor))
        self.assertEqual(self.non_invertible.det, 0.0)
        self.assertEqual(self.non_symm.det, 0.009)

        # symmetrized
        self.assertArrayEqual(
            self.rand_sqtensor.symmetrized,
            0.5 * (self.rand_sqtensor + self.rand_sqtensor.trans))
        self.assertArrayEqual(self.symm_sqtensor,
                              self.symm_sqtensor.symmetrized)
        self.assertArrayAlmostEqual(
            self.non_symm.symmetrized,
            SQTensor([[0.1, 0.3, 0.25], [0.3, 0.5, 0.55], [0.25, 0.55, 0.5]]))

        # invariants
        i1 = np.trace(self.rand_sqtensor)
        i2 = self.rand_sqtensor[0, 0] * self.rand_sqtensor[1, 1] + \
             self.rand_sqtensor[1, 1] * self.rand_sqtensor[2, 2] + \
             self.rand_sqtensor[2, 2] * self.rand_sqtensor[0, 0] - \
             self.rand_sqtensor[0, 1] * self.rand_sqtensor[1, 0] - \
             self.rand_sqtensor[0, 2] * self.rand_sqtensor[2, 0] - \
             self.rand_sqtensor[2, 1] * self.rand_sqtensor[1, 2]
        i3 = np.linalg.det(self.rand_sqtensor)
        self.assertArrayAlmostEqual([i1, i2, i3],
                                    self.rand_sqtensor.principal_invariants)

    def test_symmetry(self):
        self.assertTrue(self.symm_sqtensor.is_symmetric())
        self.assertFalse(self.non_symm.is_symmetric())
        self.assertTrue(self.low_val.is_symmetric())
        self.assertFalse(self.low_val.is_symmetric(tol=1e-8))

    def test_rotation(self):
        self.assertTrue(self.rotation.is_rotation())
        self.assertFalse(self.symm_sqtensor.is_rotation())
        self.assertTrue(self.low_val_2.is_rotation())
        self.assertFalse(self.low_val_2.is_rotation(tol=1e-8))

    def test_rotate(self):
        self.assertArrayAlmostEqual(self.non_symm.rotate(self.rotation),
                                    SQTensor([[0.531, 0.485, 0.271],
                                              [0.700, 0.5, 0.172],
                                              [0.171, 0.233, 0.068]]),
                                    decimal=3)
        self.assertRaises(ValueError, self.non_symm.rotate, self.symm_sqtensor)

    def test_get_scaled(self):
        self.assertArrayEqual(self.non_symm.get_scaled(10.),
                              SQTensor([[1, 2, 3], [4, 5, 6], [2, 5, 5]]))

    def test_polar_decomposition(self):
        u, p = self.rand_sqtensor.polar_decomposition()
        self.assertArrayAlmostEqual(np.dot(u, p), self.rand_sqtensor)
        self.assertArrayAlmostEqual(np.eye(3),
                                    np.dot(u, np.conjugate(np.transpose(u))))

    def test_zeroed(self):
        self.assertArrayEqual(
            self.low_val.zeroed(),
            SQTensor([[0, 1 + 1e-5, 0], [1 + 1e-6, 0, 0], [0, 0, 1 + 1e-5]]))
        self.assertArrayEqual(
            self.low_val.zeroed(tol=1e-6),
            SQTensor([[1e-6, 1 + 1e-5, 1e-6], [1 + 1e-6, 1e-6, 1e-6],
                      [0, 0, 1 + 1e-5]]))
        self.assertArrayEqual(
            SQTensor([[1e-6, -30, 1], [1e-7, 1, 0], [1e-8, 0, 1]]).zeroed(),
            SQTensor([[0, -30, 1], [0, 1, 0], [0, 0, 1]]))