Пример #1
0
    def testFrustum_shell(self):

        # In limit of thickness approaching radius, should recover regular formulas
        self.assertEqual(f.frustumShellVol(rb, rb, rb, h, False),
                         f.frustumVol(rb, rb, h, False))
        self.assertEqual(f.frustumShellVol(2 * rt, 2 * rt, rt, h, True),
                         f.frustumVol(rt, rt, h, False))

        self.assertEqual(f.frustumShellCG(rb, rb, rb, h, False),
                         f.frustumCG(rb, rb, h, False))
        self.assertEqual(f.frustumShellCG(2 * rt, 2 * rt, rt, h, True),
                         f.frustumCG(rt, rt, h, False))

        self.assertEqual(f.frustumShellIzz(rb, rb, rb, h, False),
                         f.frustumIzz(rb, rb, h, False))
        self.assertEqual(f.frustumShellIzz(2 * rt, 2 * rt, rt, h, True),
                         f.frustumIzz(rt, rt, h, False))

        self.assertAlmostEqual(f.frustumShellIxx(rb, rb, rb - eps, h, False),
                               f.frustumIxx(rb, rb, h, False))
        self.assertAlmostEqual(
            f.frustumShellIxx(2 * rt, 2 * rt, rt - eps, h, True),
            f.frustumIxx(rt, rt, h, False))
Пример #2
0
    def compute(self, inputs, outputs):
        # Unpack variables for thickness and average radius at each can interface
        twall = inputs["t_full"]
        Rb = 0.5 * inputs["d_full"][:-1]
        Rt = 0.5 * inputs["d_full"][1:]
        zz = inputs["z_full"]
        H = np.diff(zz)
        rho = inputs["rho"]
        coeff = inputs["outfitting_factor"]
        coeff = coeff + np.where(coeff < 1.0, 1.0, 0.0)

        # Total mass of cylinder
        V_shell = frustum.frustumShellVol(Rb, Rt, twall, H)
        mass = outputs["mass"] = coeff * rho * V_shell

        # Center of mass of each can/section
        cm_section = zz[:-1] + frustum.frustumShellCG(Rb, Rt, twall, H)
        outputs["section_center_of_mass"] = cm_section

        # Center of mass of cylinder
        V_shell += eps
        outputs["center_of_mass"] = np.dot(V_shell, cm_section) / V_shell.sum()

        # Moments of inertia
        Izz_section = coeff * rho * frustum.frustumShellIzz(Rb, Rt, twall, H)
        Ixx_section = Iyy_section = coeff * rho * frustum.frustumShellIxx(Rb, Rt, twall, H)

        # Sum up each cylinder section using parallel axis theorem
        I_base = np.zeros((3, 3))
        for k in range(Izz_section.size):
            R = np.array([0.0, 0.0, cm_section[k] - zz[0]])
            Icg = util.assembleI([Ixx_section[k], Iyy_section[k], Izz_section[k], 0.0, 0.0, 0.0])

            I_base += Icg + mass[k] * (np.dot(R, R) * np.eye(3) - np.outer(R, R))

        outputs["I_base"] = util.unassembleI(I_base)

        # Compute costs based on "Optimum Design of Steel Structures" by Farkas and Jarmai
        # All dimensions for correlations based on mm, not meters.
        R_ave = 0.5 * (Rb + Rt)
        taper = np.minimum(Rb / Rt, Rt / Rb)
        nsec = twall.size
        mshell = rho * V_shell
        mshell_tot = np.sum(rho * V_shell)
        k_m = inputs["material_cost_rate"]  # 1.1 # USD / kg carbon steel plate
        k_f = inputs["labor_cost_rate"]  # 1.0 # USD / min labor
        k_p = inputs["painting_cost_rate"]  # USD / m^2 painting
        k_e = 0.064  # Industrial electricity rate $/kWh https://www.eia.gov/electricity/monthly/epm_table_grapher.php?t=epmt_5_6_a
        e_f = 15.9  # Electricity usage kWh/kg for steel
        e_fo = 26.9  # Electricity usage kWh/kg for stainless steel

        # Cost Step 1) Cutting flat plates for taper using plasma cutter
        cutLengths = 2.0 * np.sqrt((Rt - Rb) ** 2.0 + H ** 2.0)  # Factor of 2 for both sides
        # Cost Step 2) Rolling plates
        # Cost Step 3) Welding rolled plates into shells (set difficulty factor based on tapering with logistic function)
        theta_F = 4.0 - 3.0 / (1 + np.exp(-5.0 * (taper - 0.75)))
        # Cost Step 4) Circumferential welds to join cans together
        theta_A = 2.0

        # Labor-based expenses
        K_f = k_f * (
            manufacture.steel_cutting_plasma_time(cutLengths, twall)
            + manufacture.steel_rolling_time(theta_F, R_ave, twall)
            + manufacture.steel_butt_welding_time(theta_A, nsec, mshell_tot, cutLengths, twall)
            + manufacture.steel_butt_welding_time(theta_A, nsec, mshell_tot, 2 * np.pi * Rb[1:], twall[1:])
        )

        # Cost step 5) Painting- outside and inside
        theta_p = 2
        K_p = k_p * theta_p * 2 * (2 * np.pi * R_ave * H).sum()

        # Cost step 6) Outfitting with electricity usage
        K_o = np.sum(1.5 * k_m * (coeff - 1.0) * mshell)

        # Material cost with waste fraction, but without outfitting,
        K_m = 1.21 * np.sum(k_m * mshell)

        # Electricity usage
        K_e = np.sum(k_e * (e_f * mshell + e_fo * (coeff - 1.0) * mshell))

        # Assemble all costs for now
        tempSum = K_m + K_e + K_o + K_p + K_f

        # Capital cost share from BLS MFP by NAICS
        K_c = 0.118 * tempSum / (1.0 - 0.118)

        outputs["cost"] = tempSum + K_c
Пример #3
0
    def compute(self, inputs, outputs):
        # Unpack variables for thickness and average radius at each can interface
        twall = inputs['t_full']
        Rb = 0.5 * inputs['d_full'][:-1]
        Rt = 0.5 * inputs['d_full'][1:]
        zz = inputs['z_full']
        H = np.diff(zz)
        rho = inputs['material_density']
        coeff = inputs['outfitting_factor']
        if coeff < 1.0: coeff += 1.0

        # Total mass of cylinder
        V_shell = frustum.frustumShellVol(Rb, Rt, twall, H)
        outputs['mass'] = coeff * rho * V_shell

        # Center of mass of each can/section
        cm_section = zz[:-1] + frustum.frustumShellCG(Rb, Rt, twall, H)
        outputs['section_center_of_mass'] = cm_section

        # Center of mass of cylinder
        V_shell += eps
        outputs['center_of_mass'] = np.dot(V_shell, cm_section) / V_shell.sum()

        # Moments of inertia
        Izz_section = frustum.frustumShellIzz(Rb, Rt, twall, H)
        Ixx_section = Iyy_section = frustum.frustumShellIxx(Rb, Rt, twall, H)

        # Sum up each cylinder section using parallel axis theorem
        I_base = np.zeros((3, 3))
        for k in range(Izz_section.size):
            R = np.array([0.0, 0.0, cm_section[k]])
            Icg = assembleI([
                Ixx_section[k], Iyy_section[k], Izz_section[k], 0.0, 0.0, 0.0
            ])

            I_base += Icg + V_shell[k] * (np.dot(R, R) * np.eye(3) -
                                          np.outer(R, R))

        # All of the mass and volume terms need to be multiplied by density
        I_base *= coeff * rho

        outputs['I_base'] = unassembleI(I_base)

        # Compute costs based on "Optimum Design of Steel Structures" by Farkas and Jarmai
        # All dimensions for correlations based on mm, not meters.
        R_ave = 0.5 * (Rb + Rt)
        taper = np.minimum(Rb / Rt, Rt / Rb)
        nsec = twall.size
        mplate = rho * V_shell.sum()
        k_m = inputs['material_cost_rate']  #1.1 # USD / kg carbon steel plate
        k_f = inputs['labor_cost_rate']  #1.0 # USD / min labor
        k_p = inputs['painting_cost_rate']  #USD / m^2 painting

        # Cost Step 1) Cutting flat plates for taper using plasma cutter
        cutLengths = 2.0 * np.sqrt(
            (Rt - Rb)**2.0 + H**2.0)  # Factor of 2 for both sides
        # Cost Step 2) Rolling plates
        # Cost Step 3) Welding rolled plates into shells (set difficulty factor based on tapering with logistic function)
        theta_F = 4.0 - 3.0 / (1 + np.exp(-5.0 * (taper - 0.75)))
        # Cost Step 4) Circumferential welds to join cans together
        theta_A = 2.0

        # Labor-based expenses
        K_f = k_f * (manufacture.steel_cutting_plasma_time(cutLengths, twall) +
                     manufacture.steel_rolling_time(theta_F, R_ave, twall) +
                     manufacture.steel_butt_welding_time(
                         theta_A, nsec, mplate, cutLengths, twall) +
                     manufacture.steel_butt_welding_time(
                         theta_A, nsec, mplate, 2 * np.pi * Rb[1:], twall[1:]))

        # Cost step 5) Painting- outside and inside
        theta_p = 2
        K_p = k_p * theta_p * 2 * (2 * np.pi * R_ave * H).sum()

        # Cost step 6) Outfitting
        K_o = 1.5 * k_m * (coeff - 1.0) * mplate

        # Material cost, without outfitting
        K_m = k_m * mplate

        # Assemble all costs
        outputs['cost'] = K_m + K_o + K_p + K_f