Example #1
0
    def test_calc_moisture_forces_invalid_input_errors(self):
        """Sends invalid inputs to the function, expects the proper error"""
        (valid_lam, valid_mat_list) = assemble_valid_laminate()
        valid_Z = clt.assemble_Z(valid_lam)

        self.assertRaises(
            clt.LaminateLayupError,
            clt.calc_moisture_forces,
            valid_mat_list,
            valid_lam,
            None  # Tests for invalid Z_vector
        )

        self.assertRaises(
            clt.LaminateLayupError,
            clt.calc_moisture_forces,
            valid_mat_list,
            None,  # Tests for invalid lam
            valid_Z)

        self.assertRaises(
            clt.LaminateLayupError,
            clt.calc_moisture_forces,
            None,  # Tests for invalid mat_list
            valid_mat_list,
            valid_Z)
Example #2
0
    def test_assemble_ABD_invalid_input_errors(self):
        """Sends invalid inputs to the function, expects the proper error"""
        valid_mat_list = [
            {
                'X': 1
            },
        ]
        (valid_lam, _) = assemble_valid_laminate()
        valid_Z = clt.assemble_Z(valid_lam)

        self.assertRaises(
            clt.LaminateLayupError,
            clt.assemble_ABD,
            valid_mat_list,
            valid_lam,
            None  # Tests for invalid Z_vector
        )

        self.assertRaises(
            clt.LaminateLayupError,
            clt.assemble_ABD,
            valid_mat_list,
            None,  # Tests for invalid lam
            valid_Z)

        self.assertRaises(
            clt.LaminateLayupError,
            clt.assemble_ABD,
            None,  # Tests for invalid mat_list
            valid_mat_list,
            valid_Z)
Example #3
0
 def test_known_layup_returns_expected_Z_vector(self):
     """Sends a lam with known correct Z_vector and compares to returned"""
     (lam, _) = assemble_valid_laminate()
     Z_vector = clt.assemble_Z(lam)
     Z_vector = [round(z, 6) for z in Z_vector]
     expected_Z_vector = [
         -5e-04, -4e-04, -3e-04, -2e-04, -1e-04, 0, 1e-04, 2e-04, 3e-04,
         4e-04, 5e-04
     ]
     self.assertEqual(Z_vector, expected_Z_vector)
Example #4
0
    def test_assemble_ABD_known_input_returns_correct_result(self):
        """Sends known input to the function and expects a known output,
        allowing for 0.1% error.
        Values come from Nasa Mechanics of Laminated Composite Plates
        Page 38 - Example 2"""
        mat1 = {
            "E1": 20010000.0,
            "E2": 1301000.0,
            "n12": 0.3,
            "G12": 1001000.0,
        }
        mat_list = (mat1, )
        # Initializes dictionary of the laminate layup configurations
        # thk is thickness; ang is angle; mat_id is material id
        lam = {"thk": [], "ang": [], "mat_id": []}

        # Ply 1
        lam['thk'].append(0.005)
        lam['ang'].append(45)
        lam['mat_id'].append(0)

        # Ply 2
        lam['thk'].append(0.005)
        lam['ang'].append(0)
        lam['mat_id'].append(0)

        Z = clt.assemble_Z(lam)

        expected_A = numpy.array([[133420, 24735,
                                   23523], [24735, 39325, 23523],
                                  [23523, 23523, 30819]])
        expected_B = numpy.array([[169.6, -52.02, -58.80],
                                  [-52.02, -65.59, -58.80],
                                  [-58.80, -58.80, -52.02]])
        expected_D = numpy.array([[1.1118, 0.2061, 0.1960],
                                  [0.2061, 0.3277, 0.1960],
                                  [0.1960, 0.1960, 0.2568]])
        expected_ABD = numpy.zeros((6, 6))
        expected_ABD[:3, :3] = expected_A
        expected_ABD[:3, 3:6] = expected_ABD[3:6, :3] = expected_B
        expected_ABD[3:6, 3:6] = expected_D

        returned_ABD = clt.assemble_ABD(mat_list, lam, Z)

        for rABD, eABD in zip(numpy.nditer(returned_ABD),
                              numpy.nditer(expected_ABD)):
            if rABD == 0 or eABD == 0:
                continue
            else:
                error = rABD / eABD
            self.assertTrue(0.999 < error < 1.001)
Example #5
0
    def test_calc_moistures_forces_known_input_returns_expected_result(self):
        """Sends known input to the function and expects a known output,
        allowing for 0.1% error.
        Values come from Nasa Mechanics of Laminated Composite Plates
        Page 53 - Example 5"""
        mat1 = {
            "E1": 20010000.0,
            "E2": 1301000.0,
            "n12": 0.3,
            "G12": 1001000.0,
            "b1": 0.01,
            "b2": 0.35,
        }
        mat_list = (mat1, )
        # Initializes dictionary of the laminate layup configurations
        # thk is thickness; ang is angle; mat_id is material id
        lam = {"thk": [], "ang": [], "mat_id": []}

        # Ply 1
        lam['thk'].append(0.005)
        lam['ang'].append(0)
        lam['mat_id'].append(0)

        # Ply 2
        lam['thk'].append(0.005)
        lam['ang'].append(45)
        lam['mat_id'].append(0)

        # Ply 3
        lam['thk'].append(0.005)
        lam['ang'].append(45)
        lam['mat_id'].append(0)

        # Ply 4
        lam['thk'].append(0.005)
        lam['ang'].append(0)
        lam['mat_id'].append(0)

        Z = clt.assemble_Z(lam)

        returned_Nm = clt.calc_moisture_forces(mat_list, lam, Z, dM=0.007)
        expected_Nm = numpy.array([51.7, 60.4, -4.3])

        for rNm, eNm in zip(numpy.nditer(returned_Nm),
                            numpy.nditer(expected_Nm)):
            if rNm == 0 or eNm == 0:
                continue
            else:
                error = rNm / eNm
            self.assertTrue(0.999 < error < 1.001)
Example #6
0
    def test_calc_thermal_forces_known_input_returns_expected_result(self):
        """Sends known input to the function and expects a known output,
        allowing for 0.1% error.
        Values come from Nasa Mechanics of Laminated Composite Plates
        Page 51 - Example 4"""
        mat1 = {
            "E1": 20010000.0,
            "E2": 1301000.0,
            "n12": 0.3,
            "G12": 1001000.0,
            "a1": -0.04e-6,
            "a2": 18e-6,
        }
        mat_list = (mat1, )
        # Initializes dictionary of the laminate layup configurations
        # thk is thickness; ang is angle; mat_id is material id
        lam = {"thk": [], "ang": [], "mat_id": []}

        # Ply 1
        lam['thk'].append(0.005)
        lam['ang'].append(0)
        lam['mat_id'].append(0)

        # Ply 2
        lam['thk'].append(0.005)
        lam['ang'].append(45)
        lam['mat_id'].append(0)

        # Ply 3
        lam['thk'].append(0.005)
        lam['ang'].append(45)
        lam['mat_id'].append(0)

        # Ply 4
        lam['thk'].append(0.005)
        lam['ang'].append(0)
        lam['mat_id'].append(0)

        Z = clt.assemble_Z(lam)

        returned_Nt = clt.calc_thermal_forces(mat_list, lam, Z, dT=-155.6)
        expected_Nt = numpy.array([-33.57, -60.42, 12.83])

        for rNt, eNt in zip(numpy.nditer(returned_Nt),
                            numpy.nditer(expected_Nt)):
            if rNt == 0 or eNt == 0:
                continue
            else:
                error = rNt / eNt
            self.assertTrue(0.999 < error < 1.001)
Example #7
0
    def Profile(self, coord_sys, axis, var, step):
        """ Plots stress/strain in LCS or MCS against Z vector. """

        # Sets plot dimension
        fig = plt.figure()
        #plt.figure(figsize=(10, 8))

        Z = clt.assemble_Z(self.lam)

        X = {
            "inf": np.zeros((self.num_layers)),
            "sup": np.zeros((self.num_layers))
        }
        Y = {
            "inf": np.zeros((self.num_layers)),
            "sup": np.zeros((self.num_layers))
        }

        P = np.zeros((self.num_layers * 2, 2))

        # Sets the proper names
        if coord_sys == "MCS":
            if axis == 0:
                axis_name = "1"
            elif axis == 1:
                axis_name = "2"
            else:
                axis_name = "6"
        else:
            if axis == 0:
                axis_name = "x"
            elif axis == 1:
                axis_name = "y"
            else:
                axis_name = "xy"

        # Formats the plot
        plt.title('Profile ' + coord_sys + '-' + axis_name + ' ' + var)
        plt.xlabel(var + ' (' + coord_sys + '-' + axis_name + ')')
        plt.ticklabel_format(style='sci', axis='x', scilimits=(0, 0))
        plt.ylabel('Z coordinate')
        plt.grid(True)

        # Iterates the layers, add data to plot
        for layer in range(self.num_layers):
            X["inf"][layer] = self.res[step][coord_sys][var]["inf"][axis][
                layer]
            Y["inf"][layer] = Z[layer]
            X["sup"][layer] = self.res[step][coord_sys][var]["sup"][axis][
                layer]
            Y["sup"][layer] = Z[layer + 1]
            P[layer * 2] = [X["inf"][layer], Y["inf"][layer]]
            P[layer * 2 + 1] = [X["sup"][layer], Y["sup"][layer]]
            plt.fill_betweenx([P[layer * 2, 1], P[layer * 2 + 1, 1]],
                              [P[layer * 2, 0], P[layer * 2 + 1, 0]],
                              hatch="//",
                              facecolor="none",
                              edgecolor="r",
                              lw=1.0)

        # Adds main lines
        plt.plot(P[:, 0], P[:, 1], color="r", lw=2.5)
        plt.plot([0] * (self.num_layers + 1), Z, color="b", lw=2.5)

        # Displays the plot
        if self.display:
            plt.show()

        if self.save:
            fig.savefig("plots/profile.png")

        plt.close(fig)
        """
Example #8
0
 def test_valid_layup_to_assemble_Z_returns_valid_numpy_array(self):
     """Z_vector returned by the function must always be a np.ndarray"""
     (lam, _) = assemble_valid_laminate()
     Z_vector = clt.assemble_Z(lam)
     self.assertTrue(isinstance(Z_vector, numpy.ndarray))