def test_bearing_link_global_index():
    b0 = BearingElement(n=0, n_link=3, kxx=1, cxx=1)
    idx = b0.dof_global_index()
    assert idx.x_0 == 0
    assert idx.y_0 == 1
    print(idx)
    assert idx.x_3 == 12
    assert idx.y_3 == 13
def test_bearing_link_matrices():
    b0 = BearingElement(n=0, n_link=3, kxx=1, cxx=1)
    # fmt: off
    M = np.array([[1, 0, -1, 0], [0, 1, 0, -1], [-1, 0, 1, 0], [0, -1, 0, 1]])
    # fmt: on

    assert_allclose(b0.K(0), M)
    assert_allclose(b0.C(0), M)
def test_bearing_error2():
    with pytest.raises(ValueError) as excinfo:
        BearingElement(4,
                       kxx=[7e8, 8e8, 9e8],
                       cxx=[0, 0, 0, 0],
                       frequency=[10, 100, 1000, 10000])
    assert ("Arguments (coefficients and frequency) "
            "must have the same dimension" in str(excinfo.value))

    with pytest.raises(ValueError) as excinfo:
        BearingElement(4, kxx=[6e8, 7e8, 8e8, 9e8], cxx=[0, 0, 0, 0, 0])
    assert ("Arguments (coefficients and frequency) "
            "must have the same dimension" in str(excinfo.value))
def test_bearing_len_3():
    bearing = BearingElement(
        n=0,
        kxx=[481, 4810, 18810],
        cxx=[3.13, 10.81, 22.99],
        kyy=[481, 4810, 18810],
        kxy=[194, 2078, 8776],
        kyx=[-194, -2078, -8776],
        cyy=[3.13, 10.81, 22.99],
        cxy=[0.276, 0.69, 1.19],
        cyx=[-0.276, -0.69, -1.19],
        frequency=[115.19, 345.575, 691.15],
    )
    assert_allclose(bearing.kxx_interpolated(115.19), 481, rtol=1e5)
def test_bearing_len_2():
    bearing = BearingElement(
        n=0,
        kxx=[481, 4810],
        cxx=[3.13, 10.81],
        kyy=[481, 4810],
        kxy=[194, 2078],
        kyx=[-194, -2078],
        cyy=[3.13, 10.81],
        cxy=[0.276, 0.69],
        cyx=[-0.276, -0.69],
        frequency=[115.19, 345.575],
    )
    assert_allclose(bearing.kxx_interpolated(115.19), 481, rtol=1e5)
def test_save_load(bearing0, bearing_constant, bearing_6dof):
    file = Path(tempdir) / "bearing0.toml"
    bearing0.save(file)
    bearing0_loaded = BearingElement.load(file)
    assert bearing0 == bearing0_loaded

    file = Path(tempdir) / "bearing_constant.toml"
    bearing_constant.save(file)
    bearing_constant_loaded = BearingElement.load(file)
    assert bearing_constant == bearing_constant_loaded

    file = Path(tempdir) / "bearing_6dof.toml"
    bearing_6dof.save(file)
    bearing_6dof_loaded = BearingElement6DoF.load(file)
    assert bearing_6dof == bearing_6dof_loaded
def test_from_table():
    bearing_file = (os.path.dirname(os.path.realpath(__file__)) +
                    "/data/bearing_seal_si.xls")

    bearing = BearingElement.from_table(0, bearing_file)
    assert bearing.n == 0
    assert_allclose(bearing.frequency[2], 523.5987755985)
    assert_allclose(bearing.kxx.coefficient[2], 53565700)

    # bearing with us units
    bearing_file = (os.path.dirname(os.path.realpath(__file__)) +
                    "/data/bearing_seal_us.xls")
    bearing = BearingElement.from_table(0, bearing_file)
    assert bearing.n == 0
    assert_allclose(bearing.frequency[2], 523.5987755985)
    assert_allclose(bearing.kxx.coefficient[2], 53565700)
def bearing1():
    # using lists
    Kxx_bearing = [
        8.5e07,
        1.1e08,
        1.3e08,
        1.6e08,
        1.8e08,
        2.0e08,
        2.3e08,
        2.5e08,
        2.6e08,
    ]
    Kyy_bearing = np.array([
        9.2e07, 1.1e08, 1.4e08, 1.6e08, 1.9e08, 2.1e08, 2.3e08, 2.5e08, 2.6e08
    ])
    Cxx_bearing = np.array([
        226837, 211247, 197996, 185523, 174610, 163697, 153563, 144209, 137973
    ])
    Cyy_bearing = np.array([
        235837, 211247, 197996, 185523, 174610, 163697, 153563, 144209, 137973
    ])
    wb = [314.2, 418.9, 523.6, 628.3, 733.0, 837.8, 942.5, 1047.2, 1151.9]
    bearing1 = BearingElement(
        4,
        kxx=Kxx_bearing,
        kyy=Kyy_bearing,
        cxx=Cxx_bearing,
        cyy=Cyy_bearing,
        frequency=wb,
    )
    return bearing1
def test_bearing_error_speed_not_given():
    speed = np.linspace(0, 10000, 5)
    kx = 1e8 * speed
    cx = 1e8 * speed
    with pytest.raises(Exception) as excinfo:
        BearingElement(-1, kxx=kx, cxx=cx)
    assert ("Arguments (coefficients and frequency)"
            " must have the same dimension" in str(excinfo.value))
示例#10
0
def test_st_point_mass_elements_odd_length():
    tim0 = ShaftElement(L=0.25, idl=0, odl=0.05, material=steel)
    tim1 = ShaftElement(L=0.25, idl=0, odl=0.05, material=steel)
    shaft_elm = [tim0, tim1]

    disk0 = DiskElement(n=1, m=20, Id=1, Ip=1)

    brg0 = BearingElement(n=0, kxx=1e6, cxx=1e3, n_link=3)
    brg1 = BearingElement(n=2, kxx=1e6, cxx=1e3, n_link=4)
    sup0 = BearingElement(n=3, kxx=1e6, cxx=1e3)
    sup1 = BearingElement(n=4, kxx=1e6, cxx=1e3)

    pm0 = ST_PointMass(n=3, m=[1, 2], is_random=["m"])
    pm1 = ST_PointMass(n=4, m=[1, 2, 3], is_random=["m"])

    with pytest.raises(ValueError) as ex:
        ST_Rotor(shaft_elm, [disk0], [brg0, brg1, sup0, sup1], [pm0, pm1])
    assert "not all random point mass lists have same length." in str(ex.value)
def test_save_load(bearing0, bearing_constant, bearing_6dof, magnetic_bearing):
    file = Path(tempdir) / "bearing0.toml"
    bearing0.save(file)
    bearing0_loaded = BearingElement.load(file)
    assert bearing0 == bearing0_loaded

    file = Path(tempdir) / "bearing_constant.toml"
    bearing_constant.save(file)
    bearing_constant_loaded = BearingElement.load(file)
    assert bearing_constant == bearing_constant_loaded

    file = Path(tempdir) / "bearing_6dof.toml"
    bearing_6dof.save(file)
    bearing_6dof_loaded = BearingElement6DoF.load(file)
    assert bearing_6dof == bearing_6dof_loaded

    file = Path(tempdir) / "magnetic_bearing.toml"
    magnetic_bearing.save(file)
    magnetic_bearing_loaded = MagneticBearingElement.load(file)
    assert magnetic_bearing == magnetic_bearing_loaded
示例#12
0
def report2():
    # rotor type: single double overhung
    i_d = 0.0
    o_d = 0.05
    n = 50
    L = [0.03 for _ in range(n)]

    shaft_elem = [
        ShaftElement(l,
                     i_d,
                     o_d,
                     material=steel,
                     shear_effects=True,
                     rotary_inertia=True,
                     gyroscopic=True) for l in L
    ]

    disk0 = DiskElement.from_geometry(n=0,
                                      material=steel,
                                      width=0.07,
                                      i_d=0.05,
                                      o_d=0.28)
    disk1 = DiskElement.from_geometry(n=50,
                                      material=steel,
                                      width=0.07,
                                      i_d=0.05,
                                      o_d=0.35)

    stfx = 1e6
    stfy = 0.8e6
    bearing0 = BearingElement(15, kxx=stfx, kyy=stfy, cxx=1000)
    bearing1 = BearingElement(35, kxx=stfx, kyy=stfy, cxx=1000)

    rotor = Rotor(shaft_elem, [disk0, disk1], [bearing0, bearing1])

    minspeed = 3820.0
    maxspeed = 9550.0
    machine_type = "pump"
    units = "rpm"

    return Report(rotor, minspeed, maxspeed, machine_type, units)
示例#13
0
def report0():
    # rotor type: between bearings
    i_d = 0.0
    o_d = 0.05
    n = 50
    L = [0.03 for _ in range(n)]

    shaft_elem = [
        ShaftElement(l,
                     i_d,
                     o_d,
                     material=steel,
                     shear_effects=True,
                     rotary_inertia=True,
                     gyroscopic=True) for l in L
    ]

    disk0 = DiskElement.from_geometry(n=15,
                                      material=steel,
                                      width=0.07,
                                      i_d=0.05,
                                      o_d=0.28)
    disk1 = DiskElement.from_geometry(n=35,
                                      material=steel,
                                      width=0.07,
                                      i_d=0.05,
                                      o_d=0.35)

    stfx = 1e6
    stfy = 0.8e6
    bearing0 = BearingElement(0, kxx=stfx, kyy=stfy, cxx=1000)
    bearing1 = BearingElement(50, kxx=stfx, kyy=stfy, cxx=1000)

    rotor = Rotor(shaft_elem, [disk0, disk1], [bearing0, bearing1])

    minspeed = 400.0
    maxspeed = 1000.0
    machine_type = "compressor"
    units = "rad/s"

    return Report(rotor, minspeed, maxspeed, machine_type, units)
示例#14
0
    def random_var(self, is_random, *args):
        """Generate a list of objects as random attributes.

        This function creates a list of objects with random values for selected
        attributes from ross.BearingElement.

        Parameters
        ----------
        is_random : list
            List of the object attributes to become stochastic.
        *args : dict
            Dictionary instanciating the ross.BearingElement class.
            The attributes that are supposed to be stochastic should be
            set as lists of random variables.

        Returns
        -------
        f_list : generator
            Generator of random objects.
        """
        args_dict = args[0]
        new_args = []

        try:
            for i in range(len(args_dict[is_random[0]][0])):
                arg = []
                for key, value in args_dict.items():
                    if key in is_random:
                        arg.append([value[j][i] for j in range(len(value))])
                    else:
                        arg.append(value)
                new_args.append(arg)

        except TypeError:
            for i in range(len(args_dict[is_random[0]])):
                arg = []
                for key, value in args_dict.items():
                    if key in is_random:
                        arg.append(value[i])
                    else:
                        arg.append(value)
                new_args.append(arg)

        f_list = (BearingElement(*arg) for arg in new_args)

        return f_list
示例#15
0
def bearing0():
    Kxx_bearing = np.array([
        8.5e07, 1.1e08, 1.3e08, 1.6e08, 1.8e08, 2.0e08, 2.3e08, 2.5e08, 2.6e08
    ])
    Kyy_bearing = np.array([
        9.2e07, 1.1e08, 1.4e08, 1.6e08, 1.9e08, 2.1e08, 2.3e08, 2.5e08, 2.6e08
    ])
    Cxx_bearing = np.array([
        226837, 211247, 197996, 185523, 174610, 163697, 153563, 144209, 137973
    ])
    Cyy_bearing = np.array([
        235837, 211247, 197996, 185523, 174610, 163697, 153563, 144209, 137973
    ])
    wb = np.array(
        [314.2, 418.9, 523.6, 628.3, 733.0, 837.8, 942.5, 1047.2, 1151.9])
    bearing0 = BearingElement(4,
                              kxx=Kxx_bearing,
                              kyy=Kyy_bearing,
                              cxx=Cxx_bearing,
                              cyy=Cyy_bearing,
                              w=wb)
    return bearing0
示例#16
0
    def stability_level_1(self, D, H, HP, oper_speed, RHO_ratio, RHOs, RHOd, unit="m"):
        """Stability analysis level 1.

        This analysis consider a anticipated cross coupling QA based on
        conditions at the normal operating point and the cross-coupling
        required to produce a zero log decrement, Q0.

        Components such as seals and impellers are not considered in this
        analysis.

        Parameters
        ----------
        D: list
            Impeller diameter, m (in.),
            Blade pitch diameter, m (in.),
        H: list
            Minimum diffuser width per impeller, m (in.),
            Effective blade height, m (in.),
        HP: list
            Rated power per stage/impeller, W (HP),
        oper_speed: float
            Operating speed, rpm,
        RHO_ratio: list
            Density ratio between the discharge gas density and the suction
            gas density per impeller (RHO_discharge / RHO_suction),
            kg/m3 (lbm/in.3),
        RHOs: float
            Suction gas density in the first stage, kg/m3 (lbm/in.3).
        RHOd: float
            Discharge gas density in the last stage, kg/m3 (lbm/in.3),
        unit: str, optional
            Adopted unit system. Options are "m" (meter) and "in" (inch)
            Default is "m"

        Attributes
        ----------
        condition: str
            not required: Stability Level 1 satisfies the analysis;
            required: Stability Level 2 is required.

        Return
        ------
        fig1: bokeh.figure
            Applied Cross-Coupled Stiffness vs. Log Decrement plot;
        fig2: bokeh.figure
            CSR vs. Mean Gas Density plot.

        Example
        -------
        >>> rotor = rotor_example()
        >>> report = Report(rotor=rotor,
        ...                 minspeed=400,
        ...                 maxspeed=1000,
        ...                 speed_units="rad/s")
        >>> stability = report.stability_level_1(D=[0.35, 0.35],
        ...                          H=[0.08, 0.08],
        ...                          HP=[10000, 10000],
        ...                          RHO_ratio=[1.11, 1.14],
        ...                          RHOd=30.45,
        ...                          RHOs=37.65,
        ...                          oper_speed=1000.0)
        >>> report.Qa
        23022.32142857143
        """
        steps = 11
        if unit == "m":
            C = 9.55
        elif unit == "in":
            C = 63.0
        else:
            raise TypeError("choose between meters (m) or inches (in)")

        if len(D) != len(H):
            raise Exception("length of D must be the same of H")

        Qa = 0.0
        cross_coupled_array = np.array([])
        # Qa - Anticipated cross-coupling for compressors - API 684 - SP6.8.5.6
        if self.machine_type == "compressor":
            Bc = 3.0
            Dc, Hc = D, H
            for i, disk in enumerate(self.rotor.disk_elements):
                if disk.n in self.disk_nodes:
                    qi = HP[i] * Bc * C * RHO_ratio[i] / (Dc[i] * Hc[i] * oper_speed)
                    Qi = np.linspace(0, 10 * qi, steps)
                    cross_coupled_array = np.append(cross_coupled_array, Qi)
                    Qa += qi

        # Qa - Anticipated cross-coupling for turbines - API 684 - SP6.8.5.6
        if self.machine_type == "turbine" or self.machine_type == "axial_flow":
            Bt = 1.5
            Dt, Ht = D, H
            for i, disk in enumerate(self.rotor.disk_elements):
                if disk.n in self.disk_nodes:
                    qi = (HP[i] * Bt * C) / (Dt[i] * Ht[i] * oper_speed)
                    Qi = np.linspace(0, 10 * qi, steps)
                    cross_coupled_array = np.append(cross_coupled_array, Qi)
                    Qa += qi

        # Defining cross-coupling range to 10*Qa - API 684 - SP6.8.5.8
        Qi = np.linspace(0, 10 * Qa, steps)
        cross_coupled_array = np.append(cross_coupled_array, Qi)
        cross_coupled_array = cross_coupled_array.reshape(
                [len(self.disk_nodes) + 1, steps]
        ).T

        log_dec = np.zeros(len(cross_coupled_array))

        # remove disks and seals from the rotor model
        bearing_list = [
            copy(b)
            for b in self.rotor.bearing_seal_elements
            if b.__class__.__name__ != "SealElement"
        ]

        # Applying cross-coupling on rotor mid-span
        if self.rotor_type == "between_bearings":
            for i, Q in enumerate(cross_coupled_array[:, -1]):
                bearings = [copy(b) for b in bearing_list]

                # cross-coupling introduced at the rotor mid-span
                n = np.round(np.mean(self.rotor.nodes))
                cross_coupling = BearingElement(n=int(n), kxx=0, cxx=0, kxy=Q, kyx=-Q)
                bearings.append(cross_coupling)

                aux_rotor = Rotor(
                    shaft_elements=self.rotor.shaft_elements,
                    disk_elements=[],
                    bearing_seal_elements=bearings,
                    rated_w=self.rotor.rated_w,
                )
                modal = aux_rotor.run_modal(speed=oper_speed * np.pi / 30)
                non_backward = modal.whirl_direction() != "Backward"
                log_dec[i] = modal.log_dec[non_backward][0]

        # Applying cross-coupling for each disk - API 684 - SP6.8.5.9
        else:
            for i, Q in enumerate(cross_coupled_array[:, :-1]):
                bearings = [copy(b) for b in bearing_list]
                # cross-coupling introduced at overhung disks
                for n, q in zip(self.disk_nodes, Q):
                    cross_coupling = BearingElement(
                        n=n, kxx=0, cxx=0, kxy=q, kyx=-q
                    )
                    bearings.append(cross_coupling)

                aux_rotor = Rotor(
                    shaft_elements=self.rotor.shaft_elements,
                    disk_elements=[],
                    bearing_seal_elements=bearings,
                    rated_w=self.rotor.rated_w,
                )
                modal = aux_rotor.run_modal(speed=oper_speed * np.pi / 30)
                non_backward = modal.whirl_direction() != "Backward"
                log_dec[i] = modal.log_dec[non_backward][0]

        # verifies if log dec is greater than zero to begin extrapolation
        cross_coupled_Qa = cross_coupled_array[:, -1]
        if log_dec[-1] >= 0:
            g = interp1d(
                cross_coupled_Qa, log_dec, fill_value="extrapolate", kind="linear"
            )
            stiff = cross_coupled_Qa[-1] * (1 + 1 / (len(cross_coupled_Qa)))
            while g(stiff) > 0:
                log_dec = np.append(log_dec, g(stiff))
                cross_coupled_Qa = np.append(cross_coupled_Qa, stiff)
                stiff += cross_coupled_Qa[-1] / (len(cross_coupled_Qa))
            Q0 = cross_coupled_Qa[-1]

        else:
            idx = min(range(len(log_dec)), key=lambda i: abs(log_dec[i]))
            Q0 = cross_coupled_Qa[idx]

        # Find value for log_dec corresponding to Qa
        log_dec_a = log_dec[np.where(cross_coupled_Qa == Qa)][0]

        # CSR - Critical Speed Ratio
        crit_speed = self.rotor.run_modal(speed=self.maxspeed).wn[0]
        CSR = self.maxspeed / crit_speed

        # RHO_mean - Average gas density
        RHO_mean = (RHOd + RHOs) / 2
        RHO = np.linspace(0, RHO_mean * 5, 501)

        # CSR_boundary - function to define the CSR boundaries
        CSR_boundary = np.piecewise(
            RHO,
            [RHO <= 16.53, RHO > 16.53, RHO == 60, RHO > 60],
            [2.5, lambda RHO: (-0.0115 * RHO + 2.69), 2.0, 0.0],
        )

        # Plotting area
        fig1 = figure(
            tools="pan, box_zoom, wheel_zoom, reset, save",
            title="Applied Cross-Coupled Stiffness vs. Log Decrement - (API 684 - SP 6.8.5.10)",
            width=640,
            height=480,
            x_axis_label="Applied Cross-Coupled Stiffness, Q (N/m)",
            y_axis_label="Log Dec",
            x_range=(0, max(cross_coupled_Qa)),
            y_range=DataRange1d(start=0),
        )
        fig1.title.text_font_size = "14pt"
        fig1.xaxis.axis_label_text_font_size = "20pt"
        fig1.yaxis.axis_label_text_font_size = "20pt"
        fig1.axis.major_label_text_font_size = "16pt"

        fig1.line(
            cross_coupled_Qa, log_dec, line_width=3, line_color=bokeh_colors[0]
        )
        fig1.circle(Qa, log_dec_a, size=8, fill_color=bokeh_colors[0])
        fig1.add_layout(
            Label(
                x=Qa,
                y=log_dec_a,
                text="Qa",
                text_font_style="bold",
                text_font_size="12pt",
                text_baseline="middle",
                text_align="left",
                y_offset=10
            )
        )

        if unit == "m":
            f = 0.062428
            x_label1 = "kg/m³"
            x_label2 = "lb/ft³"
        if unit == "in":
            f = 16.0185
            x_label1 = "lb/ft³"
            x_label2 = "kg/m³"

        fig2 = figure(
            tools="pan, box_zoom, wheel_zoom, reset, save",
            title="CSR vs. Mean Gas Density - (API 684 - SP 6.8.5.10)",
            width=640,
            height=480,
            x_axis_label=x_label1,
            y_axis_label="MCSR",
            y_range=DataRange1d(start=0),
            x_range=DataRange1d(start=0),
        )
        fig2.title.text_font_size = "14pt"
        fig2.xaxis.axis_label_text_font_size = "20pt"
        fig2.yaxis.axis_label_text_font_size = "20pt"
        fig2.axis.major_label_text_font_size = "16pt"
        fig2.extra_x_ranges = {"x_range2": Range1d(f * min(RHO), f * max(RHO))}

        fig2.add_layout(
            LinearAxis(
                x_range_name="x_range2",
                axis_label=x_label2,
                axis_label_text_font_size="11pt",
            ),
            place="below",
        )
        fig2.add_layout(
            Label(
                x=RHO_mean,
                y=CSR,
                text=self.tag,
                text_font_style="bold",
                text_font_size="12pt",
                text_baseline="middle",
                text_align="left",
                x_offset=10,
            )
        )

        for txt, x, y in zip(["Region A", "Region B"], [30, 60], [1.20, 2.75]):
            fig2.add_layout(
                Label(
                    x=x,
                    y=y,
                    text=txt,
                    text_alpha=0.4,
                    text_font_style="bold",
                    text_font_size="12pt",
                    text_baseline="middle",
                    text_align="center",
                )
            )

        fig2.line(x=RHO, y=CSR_boundary, line_width=3, line_color=bokeh_colors[0])
        fig2.circle(x=RHO_mean, y=CSR, size=8, color=bokeh_colors[0])

        # Level 1 screening criteria - API 684 - SP6.8.5.10
        idx = min(range(len(RHO)), key=lambda i: abs(RHO[i] - RHO_mean))

        if self.machine_type == "compressor":
            if Q0 / Qa < 2.0:
                condition = "required"

            if log_dec_a < 0.1:
                condition = "required"

            if 2.0 < Q0 / Qa < 10.0 and CSR > CSR_boundary[idx]:
                condition = "required"

            else:
                condition = "not required"

        if self.machine_type == "turbine" or self.machine_type == "axial flow":
            if log_dec_a < 0.1:
                condition = "required"

            else:
                condition = "not required"

        # updating attributes
        self.Q0 = Q0
        self.Qa = Qa
        self.log_dec_a = log_dec_a
        self.CSR = CSR
        self.Qratio = Q0 / Qa
        self.crit_speed = crit_speed
        self.MCS = self.maxspeed
        self.RHO_gas = RHO_mean
        self.condition = condition

        return fig1, fig2
示例#17
0
def report2():
    # rotor type: double overhung
    i_d = 0
    o_d = 0.05
    n = 6
    L = [0.25 for _ in range(n)]

    shaft_elem = [
        ShaftElement(
            l,
            i_d,
            o_d,
            material=steel,
            shear_effects=True,
            rotary_inertia=True,
            gyroscopic=True,
        ) for l in L
    ]

    disk0 = DiskElement.from_geometry(n=0,
                                      material=steel,
                                      width=0.07,
                                      i_d=0.05,
                                      o_d=0.28)
    disk1 = DiskElement.from_geometry(n=6,
                                      material=steel,
                                      width=0.07,
                                      i_d=0.05,
                                      o_d=0.28)

    stfx = [0.4e7, 0.5e7, 0.6e7, 0.7e7]
    stfy = [0.8e7, 0.9e7, 1.0e7, 1.1e7]
    freq = [400, 800, 1200, 1600]
    bearing0 = BearingElement(2, kxx=stfx, kyy=stfy, cxx=2e3, frequency=freq)
    bearing1 = BearingElement(4, kxx=stfx, kyy=stfy, cxx=2e3, frequency=freq)
    oper_clerance_brg = [bearing0, bearing1]

    rotor = Rotor(shaft_elem, [disk0, disk1], [bearing0, bearing1])

    # coefficients for minimum clearance
    stfx = [0.7e7, 0.8e7, 0.9e7, 1.0e7]
    dampx = [2.0e3, 1.9e3, 1.8e3, 1.7e3]
    freq = [400, 800, 1200, 1600]
    bearing0 = BearingElement(2, kxx=stfx, cxx=dampx, frequency=freq)
    bearing1 = BearingElement(4, kxx=stfx, cxx=dampx, frequency=freq)
    min_clearance_brg = [bearing0, bearing1]

    # coefficients for maximum clearance
    stfx = [0.4e7, 0.5e7, 0.6e7, 0.7e7]
    dampx = [2.8e3, 2.7e3, 2.6e3, 2.5e3]
    freq = [400, 800, 1200, 1600]
    bearing0 = BearingElement(2, kxx=stfx, cxx=dampx, frequency=freq)
    bearing1 = BearingElement(4, kxx=stfx, cxx=dampx, frequency=freq)
    max_clearance_brg = [bearing0, bearing1]

    config = Config()
    config.update_config(
        rotor_properties={
            "rotor_speeds": {
                "min_speed": 3820.0,
                "max_speed": 9550.0,
                "oper_speed": 8000.0,
                "trip_speed": 10500.0,
                "unit": "rpm",
            },
            "rotor_id": {
                "type": "axial_flow"
            },
        },
        bearings={
            "oper_clearance": oper_clerance_brg,
            "min_clearance": min_clearance_brg,
            "max_clearance": max_clearance_brg,
        },
        run_campbell={"speed_range": np.linspace(0, 1500, 51)},
        run_unbalance_response={
            "probes": {
                "node": [1, 4],
                "orientation": [np.pi / 2, np.pi / 2],
                "unit": "rad",
            },
            "frequency_range": np.linspace(0, 1500, 101),
            "plot_deflected_shape": {
                "speed": [615]
            },
        },
        plot_ucs={"stiffness_range": (5, 8)},
        stability_level1={
            "D": [0.35, 0.35],
            "H": [0.08, 0.08],
            "rated_power": [6000, 8000],
            "rho_ratio": [1.11, 1.14],
            "rho_suction": 30.45,
            "rho_discharge": 37.65,
            "length_unit": "m",
            "power_unit": "hp",
            "density_unit": "kg/m**3",
        },
    )

    return Report(rotor, config)
示例#18
0
def test_from_table():
    bearing_file = (os.path.dirname(os.path.realpath(__file__)) +
                    "/data/bearing_seal.xls")
    bearing = BearingElement.from_table(0, bearing_file)
    assert bearing.n == 0
    assert math.isclose(bearing.w[2], 523.6, abs_tol=0.1)
示例#19
0
def test_from_table():
    bearing_file = os.path.dirname(
        os.path.realpath(__file__)) + "/data/bearing_seal.xls"
    bearing = BearingElement.from_table(0, bearing_file)
    assert bearing.n == 0
    assert bearing.w[2] == 5000
示例#20
0
def report1():
    # rotor type: single overhung
    i_d = 0.0
    o_d = 0.05
    n = 50
    L = [0.03 for _ in range(n)]

    shaft_elem = [
        ShaftElement(
            l,
            i_d,
            o_d,
            material=steel,
            shear_effects=True,
            rotary_inertia=True,
            gyroscopic=True,
        )
        for l in L
    ]

    disk0 = DiskElement.from_geometry(
        n=0, material=steel, width=0.07, i_d=0.05, o_d=0.28
    )

    stfx = 1e6
    stfy = 0.8e6
    bearing0 = BearingElement(15, kxx=stfx, kyy=stfy, cxx=1000)
    bearing1 = BearingElement(50, kxx=stfx, kyy=stfy, cxx=1000)

    rotor = Rotor(shaft_elem, [disk0], [bearing0, bearing1])

    # coefficients for minimum clearance
    stfx = [0.7e7, 0.8e7, 0.9e7, 1.0e7]
    dampx = [2.0e3, 1.9e3, 1.8e3, 1.7e3]
    freq = [400, 800, 1200, 1600]
    bearing0 = BearingElement(0, kxx=stfx, cxx=dampx, frequency=freq)
    bearing1 = BearingElement(6, kxx=stfx, cxx=dampx, frequency=freq)
    min_clearance_brg = [bearing0, bearing1]

    # coefficients for maximum clearance
    stfx = [0.4e7, 0.5e7, 0.6e7, 0.7e7]
    dampx = [2.8e3, 2.7e3, 2.6e3, 2.5e3]
    freq = [400, 800, 1200, 1600]
    bearing0 = BearingElement(0, kxx=stfx, cxx=dampx, frequency=freq)
    bearing1 = BearingElement(6, kxx=stfx, cxx=dampx, frequency=freq)
    max_clearance_brg = [bearing0, bearing1]

    bearing_clearance_lists = [min_clearance_brg, max_clearance_brg]
    bearing_stiffness_range = (5, 8)

    speed_range = (400, 1000)
    tripspeed = 1200
    machine_type = "turbine"
    units = "rad/s"

    return Report(
        rotor,
        speed_range,
        tripspeed,
        bearing_stiffness_range,
        bearing_clearance_lists,
        machine_type,
        units,
    )
def bearing_constant():
    bearing = BearingElement(n=4, kxx=8e7, cxx=0)
    return bearing
示例#22
0
    def stability_level_1(self, D, H, HP, N, RHOd, RHOs, steps=21, unit="m"):
        """Stability analysis level 1.

        This analysis consider a anticipated cross coupling QA based on
        conditions at the normal operating point and the cross-coupling
        required to produce a zero log decrement, Q0.

        Components such as seals and impellers are not considered in this
        analysis.

        Parameters
        ----------
        D : list
            Impeller diameter, m (in.),
            Blade pitch diameter, m (in.),
        H : list
            Minimum diffuser width per impeller, m (in.),
            Effective blade height, m (in.),
        HP : list
            Rated power per stage/impeller, W (HP),
        N : float
            Operating speed, rpm,
        RHOd : float
            Discharge gas density per impeller, kg/m3 (lbm/in.3),
        RHOs : float
            Suction gas density per impeller, kg/m3 (lbm/in.3).
        steps : int
            Number of steps in the cross coupled stiffness range.
            Default is 21.
        unit : str
            Adopted unit system.
            Default is "m"

        Return
        ------

        Example
        -------

        """
        if unit == "m":
            C = 9.55
        elif unit == "in":
            C = 63.0
        else:
            raise TypeError("choose between meters (m) or inches (in)")

        if len(D) != len(H):
            raise Exception("length of D must be the same of H")

        # Qa - Anticipated cross-coupling - API 684 - SP6.8.5.6
        if self.machine_type == "compressor":
            Bc = 3.0
            Dc, Hc = D, H
            Qa = 0.0
            Qa_list = []
            for i in range(len(self.rotor.disk_elements)):
                qi = (HP[i] * Bc * C * RHOd) / (Dc[i] * Hc[i] * N * RHOs)
                Qa_list.append(qi)
                Qa += qi

        # Qa - Anticipated cross-coupling - API 684 - SP6.8.5.6
        if self.machine_type == "turbine" or self.machine_type == "axial_flow":
            Bt = 1.5
            Dt, Ht = D, H
            Qa = 0.0
            Qa_list = []
            for i in range(len(self.rotor.disk_elements)):
                qi = (HP[i] * Bt * C) / (Dt[i] * Ht[i] * N)
                Qa_list.append(qi)
                Qa += qi

        cross_coupled_stiff = np.linspace(0, 10 * Qa, steps)

        log_dec = np.zeros(len(cross_coupled_stiff))

        for i, Q in enumerate(cross_coupled_stiff):
            bearings = [copy(b) for b in self.rotor.bearing_seal_elements]

            if self.rotor_type == "between_bearings":
                # cross-coupling introduced at the rotor mid-span
                n = np.round(np.mean(self.rotor.nodes))
                cross_coupling = BearingElement(n=int(n),
                                                kxx=0,
                                                cxx=0,
                                                kxy=Q,
                                                kyx=-Q)
                bearings.append(cross_coupling)

            else:
                # cross-coupling introduced at overhung disks
                for n in self.disk_nodes:
                    cross_coupling = BearingElement(n=int(n),
                                                    kxx=0,
                                                    cxx=0,
                                                    kxy=Q,
                                                    kyx=-Q)
                    bearings.append(cross_coupling)

            aux_rotor = Rotor(
                self.rotor.shaft_elements,
                self.rotor.disk_elements,
                bearings,
                self.rotor.rated_w,
            )
            non_backward = aux_rotor.whirl_direction() != "Backward"
            log_dec[i] = aux_rotor.log_dec[non_backward][0]

        g = interp1d(cross_coupled_stiff,
                     log_dec,
                     fill_value="extrapolate",
                     kind="quadratic")
        stiff = cross_coupled_stiff[-1] * (1 + 1 / (len(cross_coupled_stiff)))

        while g(stiff) > 0:
            log_dec = np.append(log_dec, g(stiff))
            cross_coupled_stiff = np.append(cross_coupled_stiff, stiff)
            stiff += cross_coupled_stiff[-1] / (len(cross_coupled_stiff))
        Q0 = cross_coupled_stiff[-1]

        # CSR - Critical Speed Ratio
        CSR = self.maxspeed / self.rotor.run_modal(speed=self.maxspeed).wn[0]

        # RHO_mean - Average gas density
        RHO_mean = (RHOd + RHOs) / 2
        RHO = np.linspace(0, RHO_mean * 5, 201)
        Qc = np.piecewise(
            RHO,
            [RHO <= 16.53, RHO > 16.53, RHO == 60, RHO > 60],
            [2.5, lambda RHO: (-0.0115 * RHO + 2.69), 2.0, 0.0],
        )

        # Plot area
        fig1 = figure(
            tools="pan, box_zoom, wheel_zoom, reset, save",
            title=
            "Applied Cross-Coupled Stiffness vs. Log Decrement - (API 684 - SP 6.8.5.10)",
            x_axis_label="Applied Cross-Coupled Stiffness, Q (N/m)",
            y_axis_label="Log Dec",
            x_range=(0, max(cross_coupled_stiff)),
            y_range=DataRange1d(start=0),
        )
        fig1.title.text_font_size = "11pt"
        fig1.xaxis.axis_label_text_font_size = "11pt"
        fig1.yaxis.axis_label_text_font_size = "11pt"

        fig1.line(cross_coupled_stiff,
                  log_dec,
                  line_width=3,
                  line_color=bokeh_colors[0])
        fig1.add_layout(
            Span(
                location=Qa,
                dimension="height",
                line_color="black",
                line_dash="dashed",
                line_width=3,
            ))

        if unit == "m":
            f = 0.062428
            x_label1 = "kg/m³"
            x_label2 = "lb/ft³"
        if unit == "in":
            f = 16.0185
            x_label1 = "lb/ft³"
            x_label2 = "kg/m³"

        fig2 = figure(
            tools="pan, box_zoom, wheel_zoom, reset, save",
            title="CSR vs. Mean Gas Density - (API 684 - SP 6.8.5.10)",
            x_axis_label=x_label1,
            y_axis_label="MCSR",
            y_range=DataRange1d(start=0),
            x_range=DataRange1d(start=0))
        fig2.title.text_font_size = "11pt"
        fig2.xaxis.axis_label_text_font_size = "11pt"
        fig2.yaxis.axis_label_text_font_size = "11pt"
        fig2.extra_x_ranges = {"x_range2": Range1d(f * min(RHO), f * max(RHO))}

        fig2.add_layout(LinearAxis(x_range_name="x_range2",
                                   axis_label=x_label2,
                                   axis_label_text_font_size="11pt"),
                        place="below")
        fig2.add_layout(
            Label(
                x=RHO_mean,
                y=CSR,
                text=self.tag,
                text_font_style="bold",
                text_font_size="12pt",
                text_baseline="middle",
                text_align="left",
                x_offset=10,
            ))

        for txt, x, y in zip(["Region A", "Region B"], [30, 60], [1.20, 2.75]):
            fig2.add_layout(
                Label(
                    x=x,
                    y=y,
                    text=txt,
                    text_font_style="bold",
                    text_font_size="12pt",
                    text_baseline="middle",
                    text_align="center",
                ))

        fig2.line(x=RHO, y=Qc, line_width=3, line_color=bokeh_colors[0])
        fig2.circle(x=RHO_mean, y=CSR, size=8, color=bokeh_colors[0])

        plot = gridplot([[fig1, fig2]])

        return plot