Инженерный селектор стали и расчет болтовых соединений по СП 16.13330.2017

Инженерный калькулятор и справочник содержит нормативные характеристики прокатной стали по СП 16.13330.2017 «Стальные конструкции» (актуализированная редакция СНиП II-23-81*, с Изменениями № 1–5).


Нормативная база и классификация проката

  1. Фасонный прокат по ГОСТ 27772-2015 (Таблица В.5 СП 16):

    • Марки стали: С235, С245, С255, С345, С355, С390, С440, С590;
    • Согласно сноске *, расчетное сопротивление $R_y$ принимается строго по толщине полки ($t_f$);
    • Численные значения с учетом статистического контроля качества ($\gamma_m = 1{,}025$, числитель) и без контроля ($\gamma_m = 1{,}050$, знаменатель).
  2. Листовой, широкополосный прокат и трубы (Таблица В.3 СП 16):

    • Непрерывный ряд толщин до 160 мм без запрещенных межтабличных замен.
  3. Двутавры с параллельными гранями полок по ГОСТ Р 57837 (Таблица В.4 СП 16):

    • Включая открытый интервал $t > 100$ мм.
  4. Коэффициенты условий работы $\gamma_c$ (Таблица 1 СП 16):

    • Полный каталог коэффициентов $\gamma_c = 0{,}75 \dots 1{,}20$ без произвольного ручного ввода.
  5. Болтовые соединения (Таблицы Г.5 и Г.9, п. 14.2.9 СП 16):

    • Классы болтов: 5.6, 5.8, 8.8, 10.9, 12.9; диаметры: М16, М18, М20, М22, М24, М27, М30, М36, М42, М48;
    • Формулы несущей способности:
      • Срез: $N_{bs} = R_{bs} \gamma_b \gamma_c A n_s$ (формула 186);
      • Растяжение: $N_{bt} = R_{bt} \gamma_c A_{bn}$ (формула 188).
  6. Аналитические диаграммы деформирования стали (Приложение Б СП 16):

    • Варианты: OBD (упругопластическая с линейным упрочнением), OACD (с площадкой текучести), OACDEF (полная диаграмма деформирования и упрочнения).
In [1]:
import sys
from pathlib import Path

import ipywidgets as widgets
import matplotlib.pyplot as plt
import numpy as np
from IPython.display import HTML, Markdown, clear_output, display

project_dir = Path.cwd()
if str(project_dir) not in sys.path:
    sys.path.insert(0, str(project_dir))

from sp16_materials import (
    TABLE_1_GAMMA_C,
    SteelBolt,
    StructuralSteel,
    list_gamma_c_options,
    list_steel_grades,
)

print("Модуль sp16_materials успешно загружен.")
Модуль sp16_materials успешно загружен.

Интерактивный выбор стали и болтов

На диаграмме стали отображаются все узлы выбранного варианта Б.1. Для справочной диаграммы болтов отсутствующее значение растяжения остается пропуском, а не подменяется нулевой несущей способностью.

In [2]:
w_profile_type = widgets.Dropdown(
    options=[
        ("Фасонный прокат, В.5", "shapes"),
        ("Листы и трубы, В.3", "plates"),
        ("Двутавры с параллельными гранями, В.4", "beams_parallel"),
    ],
    value="shapes",
    description="Вид проката:",
    style={"description_width": "150px"},
)
w_steel_grade = widgets.Dropdown(
    options=list_steel_grades("shapes"),
    value="С255",
    description="Марка стали:",
    style={"description_width": "150px"},
)
w_thickness = widgets.BoundedFloatText(
    value=12.0,
    min=0.1,
    max=160.0,
    description="Толщина t, мм:",
    style={"description_width": "150px"},
)
w_stat_control = widgets.Checkbox(
    value=True,
    description="Статистический контроль (γm = 1.025)",
    indent=False,
)
# This is the complete Table 1 catalog; there is no hand-entered γc.
w_gamma_c = widgets.Dropdown(
    options=list_gamma_c_options(),
    value=TABLE_1_GAMMA_C["обычные условия"],
    description="γc, таблица 1:",
    style={"description_width": "150px"},
)
w_diagram_model = widgets.Dropdown(
    options=[
        ("OBD", "OBD"),
        ("OACD", "OACD"),
        ("OACDEF", "OACDEF"),
    ],
    value="OACDEF",
    description="Вариант Б.1:",
    style={"description_width": "150px"},
)
w_bolt_grade = widgets.Dropdown(
    options=["5.6", "5.8", "8.8", "10.9", "12.9"],
    value="8.8",
    description="Класс болта:",
    style={"description_width": "150px"},
)
bolt_diameters = [16, 18, 20, 22, 24, 27, 30, 36, 42, 48]
w_bolt_diameter = widgets.Dropdown(
    options=bolt_diameters,
    value=20,
    description="Диаметр, мм:",
    style={"description_width": "150px"},
)
w_special_support = widgets.Checkbox(
    value=False,
    description="ВЛ/ОРУ для диаметров из скобок таблицы Г.9",
    indent=False,
)
w_bolt_gamma_b = widgets.FloatSlider(
    value=1.0, min=0.1, max=1.0, step=0.01,
    description="γb болтов:", style={"description_width": "150px"},
)
out_panel = widgets.Output()


def _set_limits(axis, eps):
    low, high = float(np.min(eps)), float(np.max(eps))
    span = max(high - low, 1e-6)
    axis.set_xlim(low - 0.08 * span, high + 0.08 * span)


def _plot_named_points(axis, points, offsets=None):
    offsets = offsets or {}
    for index, (label, (epsilon, sigma)) in enumerate(points.items()):
        x_value = epsilon * 1000.0
        axis.scatter([x_value], [sigma], color="#d62728", s=28, zorder=5)
        axis.annotate(
            label,
            xy=(x_value, sigma),
            xytext=offsets.get(label, (6, 8 if index % 2 == 0 else -16)),
            textcoords="offset points",
            fontsize=8,
            color="#d62728",
            arrowprops={"arrowstyle": "-", "color": "#d62728", "lw": 0.8},
        )


def _plot_steel_curve(axis, eps, sig, points, title):
    x_values = eps * 1000.0
    axis.plot(x_values, sig, color="#1f77b4", lw=2.3)
    label_offsets = {
        "O": (8, 8),
        "A": (10, -22),
        "B": (10, 10),
        "C": (10, -22),
        "D": (10, 10),
        "E": (8, 10),
        "F": (8, -20),
    }
    _plot_named_points(axis, points, label_offsets)
    axis.set_title(title)
    axis.set_xlabel("ε, ‰")
    axis.set_ylabel("σ, МПа")
    axis.grid(True, linestyle=":", alpha=0.6)
    axis.axhline(0.0, color="black", lw=0.7, alpha=0.5)
    axis.axvline(0.0, color="black", lw=0.7, alpha=0.5)
    _set_limits(axis, x_values)

    # The full B.1 range includes fracture strains of tens of
    # percent, which visually compresses O-A-C-D at the origin.
    # Keep the normative full curve and add a zoom of the node
    # region so the selected variant remains readable.
    focus_labels = {"O", "A", "B", "C", "D"}
    focus_points = {
        label: value for label, value in points.items()
        if label in focus_labels
    }
    if len(focus_points) > 1:
        focus_x = max(abs(epsilon * 1000.0) for epsilon, _ in focus_points.values())
        focus_y = max(abs(sigma) for _, sigma in focus_points.values())
        inset = axis.inset_axes([0.05, 0.51, 0.47, 0.43])
        inset.plot(x_values, sig, color="#1f77b4", lw=1.6)
        _plot_named_points(inset, focus_points, label_offsets)
        inset.set_xlim(-max(2.5, 1.25 * focus_x), max(2.5, 1.25 * focus_x))
        inset.set_ylim(-max(20.0, 1.20 * focus_y), max(20.0, 1.20 * focus_y))
        inset.grid(True, linestyle=":", alpha=0.55)
        inset.axhline(0.0, color="black", lw=0.6, alpha=0.5)
        inset.axvline(0.0, color="black", lw=0.6, alpha=0.5)
        inset.set_title("Узлы O–D", fontsize=8)
        inset.tick_params(labelsize=7)
        axis.indicate_inset_zoom(inset, edgecolor="0.45", linewidth=0.8)


def on_profile_change(change):
    grades = list_steel_grades(w_profile_type.value)
    w_steel_grade.options = grades
    preferred = "С255" if "С255" in grades else grades[0]
    w_steel_grade.value = preferred


def update_view(*_):
    with out_panel:
        clear_output(wait=True)
        try:
            steel = StructuralSteel(
                grade=w_steel_grade.value,
                profile_type=w_profile_type.value,
                thickness=w_thickness.value,
                statistical_control=w_stat_control.value,
                gamma_c=w_gamma_c.value,
            )
            bolt = SteelBolt(
                grade=w_bolt_grade.value,
                diameter=w_bolt_diameter.value,
                gamma_b=w_bolt_gamma_b.value,
                gamma_c=w_gamma_c.value,
                special_support=w_special_support.value,
            )
            eps_arr, sig_arr = steel.get_diagram(
                model=w_diagram_model.value,
                n_points=180,
                signed=True,
            )
            points = steel.get_diagram_points(
                model=w_diagram_model.value,
                signed=True,
            )
        except ValueError as error:
            display(Markdown(f"**Параметры требуют уточнения:** `{error}`"))
            return

        if w_profile_type.value == "beams_parallel" and w_thickness.value > 100.0:
            display(Markdown(
                "*Для В.4 выбрана открытая нормативная область толщин `t > 100 мм`.*"
            ))

        fig, (ax_steel, ax_bolts) = plt.subplots(
            1, 2, figsize=(14.5, 5.2), dpi=110, constrained_layout=True
        )
        _plot_steel_curve(
            ax_steel,
            eps_arr,
            sig_arr,
            points,
            f"Сталь {steel.grade}, {steel.profile_type}, t={steel.thickness:g} мм"
        )

        nbs_values = []
        nbt_values = []
        for diameter in bolt_diameters:
            catalog_bolt = SteelBolt(
                grade=w_bolt_grade.value,
                diameter=diameter,
                gamma_b=w_bolt_gamma_b.value,
                gamma_c=w_gamma_c.value,
                special_support=True,
            )
            nbs_values.append(catalog_bolt.shear_capacity(1))
            tension = catalog_bolt.tension_capacity()
            nbt_values.append(np.nan if tension is None else tension)
        x_values = np.arange(len(bolt_diameters))
        width = 0.38
        ax_bolts.bar(
            x_values - width / 2, nbs_values, width,
            label="Срез Nbs (1 пл.)", color="#ff7f0e", alpha=0.85,
        )
        ax_bolts.bar(
            x_values + width / 2, nbt_values, width,
            label="Растяжение Nbt", color="#2ca02c", alpha=0.85,
        )
        ax_bolts.set_xticks(x_values)
        ax_bolts.set_xticklabels([f{diameter}" for diameter in bolt_diameters])
        ax_bolts.set_title(f"Болты класса {w_bolt_grade.value}")
        ax_bolts.set_xlabel("Диаметр по таблице Г.9")
        ax_bolts.set_ylabel("Несущая способность, кН")
        ax_bolts.grid(True, linestyle=":", alpha=0.6, axis="y")
        ax_bolts.legend(loc="upper left", fontsize=9)
        plt.show()

        display(HTML(steel.to_html()))
        display(HTML(bolt.to_html()))


w_profile_type.observe(on_profile_change, names="value")
controls = [
    w_profile_type, w_steel_grade, w_thickness, w_stat_control,
    w_gamma_c, w_diagram_model, w_bolt_grade, w_bolt_diameter,
    w_special_support, w_bolt_gamma_b,
]
for widget in controls:
    widget.observe(update_view, names="value")

steel_box = widgets.VBox(
    [
        widgets.HTML("<b>Параметры прокатной стали</b>"),
        w_profile_type, w_steel_grade, w_thickness,
        w_stat_control, w_gamma_c, w_diagram_model,
    ],
    layout=widgets.Layout(border="1px solid #ddd", padding="10px"),
)
bolt_box = widgets.VBox(
    [
        widgets.HTML("<b>Параметры болтового соединения</b>"),
        w_bolt_grade, w_bolt_diameter, w_special_support, w_bolt_gamma_b,
    ],
    layout=widgets.Layout(border="1px solid #ddd", padding="10px"),
)
display(widgets.HBox([steel_box, bolt_box]))
display(out_panel)
update_view()

Пример прямого использования

In [3]:
# Статический рендер по умолчанию: сохраняется и при nbconvert,
# даже если интерактивные Output-виджеты не сериализуются.
demo_steel = StructuralSteel(
    "С255", profile_type="shapes", thickness=12.0, gamma_c=1.0
)
demo_bolt = SteelBolt("8.8", diameter=20, gamma_b=1.0, gamma_c=1.0)
demo_eps, demo_sig = demo_steel.get_diagram(
    model="OACDEF", n_points=180, signed=True
)
demo_points = demo_steel.get_diagram_points(
    model="OACDEF", signed=True
)
demo_fig, (demo_ax_steel, demo_ax_bolts) = plt.subplots(
    1, 2, figsize=(14.5, 5.2), dpi=110, constrained_layout=True
)
_plot_steel_curve(
    demo_ax_steel, demo_eps, demo_sig, demo_points, "Сталь С255: OACDEF"
)

demo_diameters = [16, 18, 20, 22, 24, 27, 30, 36, 42, 48]
demo_nbs = []
demo_nbt = []
for diameter in demo_diameters:
    catalog_bolt = SteelBolt(
        "8.8", diameter=diameter, gamma_b=1.0, gamma_c=1.0,
        special_support=True,
    )
    demo_nbs.append(catalog_bolt.shear_capacity(1))
    capacity = catalog_bolt.tension_capacity()
    demo_nbt.append(np.nan if capacity is None else capacity)
demo_x = np.arange(len(demo_diameters))
demo_width = 0.38
demo_ax_bolts.bar(
    demo_x - demo_width / 2, demo_nbs, demo_width,
    label="Срез Nbs", color="#ff7f0e", alpha=0.85,
)
demo_ax_bolts.bar(
    demo_x + demo_width / 2, demo_nbt, demo_width,
    label="Растяжение Nbt", color="#2ca02c", alpha=0.85,
)
demo_ax_bolts.set_xticks(demo_x)
demo_ax_bolts.set_xticklabels([f{d}" for d in demo_diameters])
demo_ax_bolts.set_title("Болты класса 8.8")
demo_ax_bolts.set_xlabel("Диаметр по таблице Г.9")
demo_ax_bolts.set_ylabel("Несущая способность, кН")
demo_ax_bolts.grid(True, linestyle=":", alpha=0.6, axis="y")
demo_ax_bolts.legend(loc="upper left", fontsize=9)
plt.show()
display(HTML(demo_steel.to_html()))
display(HTML(demo_bolt.to_html()))

Характеристики стали С255 (СП 16.13330.2017)

  • Вид проката: Фасонный прокат (ГОСТ 27772, табл. В.5) (толщина t = 12.0 мм)
  • Качество проката: Со статконтролем (γm = 1.025)
  • Коэффициент условий работы: γc = 1.0
Параметр Обозначение Значение Ед. изм.
Расчетное сопротивление растяжению/сжатию/изгибуRy240.0МПа
Расчетное сопротивление по пределу прочностиRu360.0МПа
Расчетное сопротивление сдвигу (0.58 Ry)Rs139.2МПа
Расчетное сопротивление смятию торцевой поверхностиRp361.0МПа
Расчетное сопротивление смятию в шарнирах (0.5 Ry)Rlp180.0МПа
Нормативный предел текучестиRyn245.0МПа
Нормативное временное сопротивлениеRun370.0МПа
Модуль упругостиE206,000МПа
Модуль сдвигаG79,000МПа
Деформация предела текучестиεy0.001165-

Болт класса прочности 8.8, М20 (СП 16.13330.2017)

Параметр Обозначение Значение Ед. изм.
Расчетное сопротивление срезуRbs332.0МПа
Расчетное сопротивление растяжениюRbt451.0МПа
Площадь стержня бруттоA314.0мм²
Площадь сечения нетто по резьбеAbn245.0мм²
Несущая способность на срез (1 плоскость среза)Nbs104.248кН
Несущая способность на растяжениеNbt110.495кН
Коэффициент условий работы соединенияγb1.0-
Коэффициент условий работы конструкцииγc1.0-
In [4]:
steel_example = StructuralSteel("С255", profile_type="shapes", thickness=14.0)
bolt_example = SteelBolt("8.8", diameter=20, gamma_b=0.9, gamma_c=1.0)
Wx = 472.4e3  # мм³
moment = Wx * steel_example.Ry / 1e6
capacity = 4.0 * bolt_example.shear_capacity(1)
print(f"M_el = {moment:.2f} кН·м; 4 болта: Q = {capacity:.2f} кН")

# Поверочный расчет прокатной балки 25Б1 (ГОСТ Р 57837-2017)
beam_steel = StructuralSteel("С255", profile_type="beams_parallel", thickness=8.0, gamma_c=1.0)
L_m = 6.0
q_des_kN_m = 12.0
q_ser_kN_m = 10.0

W_x_cm3 = 284.7
I_x_cm4 = 3530.0
S_x_cm3 = 160.7
t_w_mm = 5.0

M_max = q_des_kN_m * (L_m ** 2) / 8.0
Q_max = q_des_kN_m * L_m / 2.0

sigma_MPa = (M_max * 1e6) / (W_x_cm3 * 1e3)
k_sigma = sigma_MPa / beam_steel.Ry

tau_MPa = (Q_max * 1e3 * S_x_cm3 * 1e3) / (I_x_cm4 * 1e4 * t_w_mm)
k_tau = tau_MPa / beam_steel.Rs

f_mm = (5.0 / 384.0) * (q_ser_kN_m * (L_m ** 4) * 1e12) / (beam_steel.E * I_x_cm4 * 1e4)
f_ult_mm = (L_m * 1000.0) / 250.0
k_def = f_mm / f_ult_mm

N_bs_1 = bolt_example.shear_capacity(1)

report_lines = [
    "### Инженерный поверочный расчет прокатной балки 25Б1 (СП 16.13330.2017)",
    "",
    f"* **Параметры элемента**: пролет $L = {L_m:.1f}$ м, сталь {beam_steel.grade} ($R_y = {beam_steel.Ry:.1f}$ МПа, $R_s = {beam_steel.Rs:.1f}$ МПа, $E = {beam_steel.E:.0f}$ МПа);",
    f"* **Нагрузки**: расчетная $q = {q_des_kN_m:.1f}$ кН/м, нормативная $q^н = {q_ser_kN_m:.1f}$ кН/м $\\implies M_{{max}} = {M_max:.1f}$ кН·м, $Q_{{max}} = {Q_max:.1f}$ кН.",
    "",
    "| Критерий проверки по СП 16 | Расчетное значение | Предельное значение | Коэффициент использования | Статус |",
    "|:---|---:|---:|---:|:---:|",
    f"| **Нормальные напряжения (п. 8.2.1)** | $\\sigma = {sigma_MPa:.1f}$ МПа | $R_y \\gamma_c = {beam_steel.Ry:.1f}$ МПа | **{k_sigma:.2f}** | **ПРОХОДИТ** |",
    f"| **Касательные напряжения (п. 8.2.1)** | $\\tau = {tau_MPa:.1f}$ МПа | $R_s \\gamma_c = {beam_steel.Rs:.1f}$ МПа | **{k_tau:.2f}** | **ПРОХОДИТ** |",
    f"| **Жесткость по прогибу (п. 15.2.1)** | $f = {f_mm:.1f}$ мм | $f_{{ult}} = {f_ult_mm:.1f}$ мм | **{k_def:.2f}** | **ПРОХОДИТ** |",
    f"| **Опорный срез узла (4 болта 8.8 М20)** | $Q = {Q_max:.1f}$ кН | $4 N_{{bs}} = {4.0 * N_bs_1:.1f}$ кН | **{Q_max / (4.0 * N_bs_1):.2f}** | **ПРОХОДИТ** |",
    "",
    f"*Вывод*: Сечение 25Б1 полностью удовлетворяет требованиям СП 16.13330.2017 с запасом по прочности {(1 - k_sigma)*100:.1f}%, по прогибу {(1 - k_def)*100:.1f}%. Опорный узел на 4 болтах 8.8 М20 имеет запас несущей способности на срез {(4.0 * N_bs_1 / Q_max - 1)*100:.0f}%.",
]
display(Markdown("\n".join(report_lines)))
M_el = 113.38 кН·м; 4 болта: Q = 375.29 кН

Инженерный поверочный расчет прокатной балки 25Б1 (СП 16.13330.2017)

  • Параметры элемента: пролет $L = 6.0$ м, сталь С255Б ($R_y = 250.0$ МПа, $R_s = 145.0$ МПа, $E = 206000$ МПа);
  • Нагрузки: расчетная $q = 12.0$ кН/м, нормативная $q^н = 10.0$ кН/м $\implies M_{max} = 54.0$ кН·м, $Q_{max} = 36.0$ кН.
Критерий проверки по СП 16 Расчетное значение Предельное значение Коэффициент использования Статус
Нормальные напряжения (п. 8.2.1) $\sigma = 189.7$ МПа $R_y \gamma_c = 250.0$ МПа 0.76 ПРОХОДИТ
Касательные напряжения (п. 8.2.1) $\tau = 32.8$ МПа $R_s \gamma_c = 145.0$ МПа 0.23 ПРОХОДИТ
Жесткость по прогибу (п. 15.2.1) $f = 23.2$ мм $f_{ult} = 24.0$ мм 0.97 ПРОХОДИТ
Опорный срез узла (4 болта 8.8 М20) $Q = 36.0$ кН $4 N_{bs} = 375.3$ кН 0.10 ПРОХОДИТ

Вывод: Сечение 25Б1 полностью удовлетворяет требованиям СП 16.13330.2017 с запасом по прочности 24.1%, по прогибу 3.3%. Опорный узел на 4 болтах 8.8 М20 имеет запас несущей способности на срез 942%.