| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196 |
- # -*- coding: utf-8 -*-
- """
- Лаба 3. Конструирование тоннельных обделок сводчатого очертания.
- Расчёт по методике (шаги 1–13), SymPy.
- Все длины в мм, углы выводятся в градусах.
- """
- from sympy import Rational, sin, cos, asin, deg, rad, N, nsimplify
- # ---------------------------------------------------------------- справочные данные
- # Табл. 1: ширина проезжей части Г (м) по длине тоннеля и категории дороги
- G_TABLE = {
- ("до 300", "I-II"): 9.0,
- ("до 300", "III"): 8.5,
- ("до 300", "IV"): 8.0,
- ("более 300", "I-II"): 8.5,
- ("более 300", "III"): 8.0,
- ("более 300", "IV"): 7.0,
- }
- # Табл. 7: замковое сечение hз (см) — диапазоны; строка = категория дороги
- # (в скобках у габарита — значение Г для тоннелей длиной более 300 м той же категории)
- HZ_TABLE = {
- "I-II": [(90, 85), (80, 75), (75, 70), (65, 60), (60, 55), (50, 45), 40], # Г-9 (8,5)
- "III": [(85, 80), (75, 70), (70, 60), (60, 55), (55, 50), 40, 40], # Г-8,5 (8)
- "IV": [(80, 75), (70, 65), (60, 55), (55, 50), (50, 45), 40, 40], # Г-8 (7)
- }
- # Табл. 7: множители к hз для пяты свода / стены / обреза фундамента по группам крепости
- def mult_group(f):
- if f <= 3:
- return {"hп": (1.4, 1.3), "hст": (1.6, 1.5), "hо": (2.0, 1.8)}
- if f <= 6:
- return {"hп": (1.3, 1.1), "hст": (1.5, 1.3), "hо": (1.8, 1.6)}
- return {"hп": (1, 1), "hст": (1.1, 1.0), "hо": (1.5, 1.5)}
- # Варианты для самостоятельной работы: (длина, категория, свод, порода, f)
- VARIANTS = {
- 1: ("до 300", "I-II", "пологий", "скальная", 4),
- 2: ("до 300", "III", "подъемистый", "скальная", 4),
- 3: ("до 300", "I-II", "пологий", "скальная", 8),
- 4: ("более 300", "III", "подъемистый", "слабая", 2),
- 5: ("до 300", "I-II", "пологий", "скальная", 6),
- 6: ("более 300", "III", "подъемистый", "слабая", 3),
- 7: ("до 300", "I-II", "пологий", "слабая", 3),
- 8: ("до 300", "I-II", "пологий", "скальная", 7),
- 9: ("до 300", "I-II", "пологий", "скальная", 5),
- 10: ("до 300", "III", "подъемистый", "скальная", 6),
- 11: ("до 300", "I-II", "пологий", "слабая", 2),
- 12: ("до 300", "I-II", "пологий", "слабая", 1),
- 13: ("более 300", "III", "подъемистый", "скальная", 4),
- 14: ("более 300", "III", "подъемистый", "слабая", 1),
- 15: ("более 300", "I-II", "пологий", "скальная", 9),
- 16: ("до 300", "IV", "подъемистый", "скальная", 4),
- 17: ("до 300", "IV", "подъемистый", "скальная", 7),
- 18: ("более 300", "III", "подъемистый", "скальная", 7),
- 19: ("более 300", "I-II", "подъемистый", "слабая", 2),
- 20: ("до 300", "I-II", "пологий", "слабая", 1),
- }
- PASSAGE = 750 # служебный проход П, мм
- STRIP = 500 # защитная полоса ЗП, мм
- I_CROSS = 0.02 # поперечный уклон проезжей части, 20 промилле
- # ---------------------------------------------------------------- расчёт
- def compute(length="до 300", category="I-II", vault="пологий", rock="скальная", f=4,
- beta=None, hz=None, hp=None, dz=None, db=None, round_deg=True):
- """Шаги 1–13 методики. Неизвестные параметры подбираются из таблиц по умолчанию
- (диапазоны берутся с верхним значением, как в примере методички)."""
- out = {}
- # --- исходные данные по таблицам
- G = Rational(int(G_TABLE[(length, category)] * 1000)) # ширина проезжей части, мм
- if dz is None:
- dz = 150 if rock == "слабая" else 100 # зазор: слабая 15 см, скальная 10 см
- dz = Rational(dz)
- if db is None:
- db = 200 if (vault == "пологий" and rock == "скальная") else 0 # бермы — только пологий свод на скальной
- db = Rational(db)
- # --- 1) пролёт в свету
- if category in ("I-II", "I или II"):
- l0 = G + 2 * PASSAGE + 2 * dz + 2 * db
- else:
- l0 = G + PASSAGE + STRIP + 2 * dz
- # --- 2) отношение пролёта к стреле подъёма
- if beta is None:
- beta = Rational(3) if vault == "пологий" else Rational(9, 4) # пологий 2,5–4; подъемистый 2,1–2,4
- # --- 3) стрела подъёма в свету
- f0 = l0 / beta
- # --- 4) радиус внутреннего очертания свода
- r0 = f0 * (4 + beta**2) / 8
- # --- 5) предварительный угол наклона пяты свода
- sin_phi_pr = l0 / (2 * r0)
- phi_pr = N(deg(asin(sin_phi_pr)))
- phi_pr_use = round(float(phi_pr)) if round_deg else float(phi_pr)
- # --- 6) сечения обделки по табл. 7
- hz_row = HZ_TABLE[category]
- hz_range = hz_row[min(f, 7) - 1]
- if hz is None:
- hz = hz_range[0] if isinstance(hz_range, tuple) else hz_range # верх диапазона, см
- hz = Rational(hz * 10) # -> мм
- grp = mult_group(f)
- if hp is None:
- hp = round(grp["hп"][0] * float(hz)) # верх диапазона множителя
- hp = Rational(hp)
- # --- 7) предварительные осевые стрела и пролёт
- f_pr = f0 + Rational(1, 2) * hz - Rational(1, 2) * hp * cos(rad(phi_pr_use))
- l_pr = l0 + hp * sin(rad(phi_pr_use))
- # --- 8) уточнённый угол пяты
- sin_phi = 4 * f_pr * l_pr / (4 * f_pr**2 + l_pr**2)
- phi = N(deg(asin(sin_phi)))
- phi_use = round(float(phi)) if round_deg else float(phi)
- # --- 9) окончательные осевые стрела и пролёт
- f_ = f0 + Rational(1, 2) * hz - Rational(1, 2) * hp * cos(rad(phi_use))
- l_ = l0 + hp * sin(rad(phi_use))
- # --- 10) расчётный (осевой) радиус свода
- r = Rational(1, 2) * l_ / sin(rad(phi_use))
- # --- 11) стрела и пролёт наружного очертания
- f1 = f_ + Rational(1, 2) * hz - Rational(1, 2) * hp * cos(rad(phi_use))
- l1 = l_ + hp * sin(rad(phi_use))
- # --- 12) радиус наружного очертания
- r1 = (4 * f1**2 + l1**2) / (8 * f1)
- # --- 13) сточный треугольник по оси проезжей части
- h_t = Rational(1, 2) * G * Rational(int(I_CROSS * 1000), 1000)
- # сечения по табл. 7 (для оформления)
- hст = round(grp["hст"][0] * float(hz))
- hо = round(grp["hо"][0] * float(hz))
- hл = round(0.8 * float(hz))
- def v(x):
- return round(float(N(x)), 1)
- out["Г"] = float(G); out["П"] = PASSAGE; out["δз"] = int(dz); out["δб"] = int(db)
- out.update({
- "1) l₀": v(l0), "2) β": float(beta), "3) f₀": v(f0), "4) r₀": v(r0),
- "5) sinφпр": round(float(sin_phi_pr), 4), "5) φпр": phi_pr_use,
- "6) hз,мм": float(hz), "6) hп,мм": float(hp), "6) hст,мм": hст, "6) hо,мм": hо, "6) hл,мм": hл,
- "7) fпр": v(f_pr), "7) lпр": v(l_pr),
- "8) sinφ": round(float(sin_phi), 4), "8) φ": phi_use,
- "9) f": v(f_), "9) l": v(l_),
- "10) r": v(r),
- "11) f₁": v(f1), "11) l₁": v(l1),
- "12) r₁": v(r1),
- "13) hт": v(h_t),
- })
- return out
- def report(title, res):
- print(f"\n=== {title} ===")
- for k, val in res.items():
- print(f" {k:14} = {val}")
- if __name__ == "__main__":
- import sys
- if len(sys.argv) > 1 and sys.argv[1] == "all":
- cols = ["1) l₀", "3) f₀", "4) r₀", "5) φпр", "6) hз,мм", "6) hп,мм",
- "8) φ", "9) f", "9) l", "10) r", "11) f₁", "11) l₁", "12) r₁", "13) hт"]
- hdr = "N " + " ".join(f"{c.split(') ')[1]:>9}" for c in cols)
- print(hdr)
- for n, (length, cat, vault, rock, f) in VARIANTS.items():
- res = compute(length, cat, vault, rock, f)
- print(f"{n:<3}" + " ".join(f"{res[c]:>9}" for c in cols))
- elif len(sys.argv) > 1 and sys.argv[1].isdigit():
- n = int(sys.argv[1])
- length, cat, vault, rock, f = VARIANTS[n]
- report(f"Вариант {n}: {length}, {cat}, {vault} свод, {rock} порода, f={f}",
- compute(length, cat, vault, rock, f))
- else:
- # Проверка на примере методички (до 300, I–II, пологий, скальная, f=4;
- # в примере методички hп = 1,4·hз = 910 мм, β = 3)
- report("Пример методички", compute(
- length="до 300", category="I-II", vault="пологий", rock="скальная", f=4,
- beta=3, hz=65, hp=910, dz=100, db=200))
|