-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathspan_layout_search.py
More file actions
120 lines (103 loc) · 4.85 KB
/
Copy pathspan_layout_search.py
File metadata and controls
120 lines (103 loc) · 4.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
"""
span_layout_search.py
跨径布置确定性搜索:给定桥梁总长和跨数范围,在"等跨"与"边跨缩短"两类
经典布置方案之间搜索,复用 design_search.find_adequate_reinforcement
判断每个候选跨径组合是否结构可行,在可行方案里选出混凝土用量最省的一个。
与 design_search.py 一样全部本地计算,不涉及 LLM。
"""
from dataclasses import dataclass
from typing import List, Optional, Tuple
import design_search
from export_utils import calculate_bridge_quantities
END_SPAN_RATIO = 0.8 # 边跨/中跨长度比:连续梁桥边跨适当缩短是常见工程做法,
# 可以降低边跨的正弯矩,让跨径分布更合理
@dataclass
class SpanLayoutCandidate:
spans: List[float]
pattern: str # "等跨" 或 "边跨缩短"
beam_h: float
num_girders: int
bar_diameter_mm: int
worst_utilization: float
total_concrete_m3: float
@dataclass
class SpanLayoutResult:
found: bool
best: Optional[SpanLayoutCandidate]
candidates: List[SpanLayoutCandidate] # 所有可行方案,按混凝土用量升序排列
message: str
def _generate_span_patterns(total_length: float, num_spans: int) -> List[Tuple[str, List[float]]]:
"""返回 (方案名, 跨径列表) 列表:等跨方案总是有;跨数 >= 3 时额外生成边跨缩短方案"""
equal_span = total_length / num_spans
patterns = [("等跨", [round(equal_span, 2)] * num_spans)]
if num_spans >= 3:
# 2 * (k*x) + (num_spans-2) * x = total_length,解出中跨长度 x
k = END_SPAN_RATIO
x = total_length / (2 * k + (num_spans - 2))
end_span = round(k * x, 2)
mid_span = round(x, 2)
spans = [end_span] + [mid_span] * (num_spans - 2) + [end_span]
patterns.append(("边跨缩短", spans))
return patterns
def find_span_layout(
total_length: float,
bridge_w: float,
pier_h: float,
q_live: float,
num_spans_min: int = 2,
num_spans_max: int = 5,
beam_h_start: float = 2.0,
current_num_girders: int = 5,
current_bar_diameter_mm: int = 25,
) -> SpanLayoutResult:
"""
在 [num_spans_min, num_spans_max] 跨数范围内,对"等跨"和"边跨缩短"两类
布置方案分别做结构可行性搜索(复用 design_search 的梁高/梁片数/主筋
直径搜索),返回所有可行方案(按混凝土用量升序),并推荐用量最省的一个。
"""
candidates: List[SpanLayoutCandidate] = []
for num_spans in range(num_spans_min, num_spans_max + 1):
for pattern_name, spans in _generate_span_patterns(total_length, num_spans):
search_result = design_search.find_adequate_reinforcement(
spans=spans,
beam_h=beam_h_start,
pier_h=pier_h,
bridge_w=bridge_w,
q_live=q_live,
current_num_girders=current_num_girders,
current_bar_diameter_mm=current_bar_diameter_mm,
)
if not search_result.found:
continue
quantities = calculate_bridge_quantities(
spans=spans, beam_h=search_result.beam_h, pier_h=pier_h, bridge_width=bridge_w
)
candidates.append(
SpanLayoutCandidate(
spans=spans,
pattern=pattern_name,
beam_h=search_result.beam_h,
num_girders=search_result.num_girders,
bar_diameter_mm=search_result.bar_diameter_mm,
worst_utilization=search_result.worst_utilization,
total_concrete_m3=quantities["total_concrete_m3"],
)
)
if not candidates:
message = (
f"总长 {total_length:.1f}m 在 {num_spans_min}~{num_spans_max} 跨范围内,"
"尝试的跨径布置方案都无法找到满足承载力要求的截面/配筋方案。"
"建议扩大跨数搜索范围(增加跨数、缩短单跨),或考虑增大桥面宽度/减小总长。"
)
return SpanLayoutResult(found=False, best=None, candidates=[], message=message)
candidates.sort(key=lambda c: c.total_concrete_m3)
best = candidates[0]
message = (
f"已对总长 {total_length:.1f}m 在 {num_spans_min}~{num_spans_max} 跨范围内搜索,"
f"找到 {len(candidates)} 个满足承载力要求的可行方案。推荐方案:"
f"{len(best.spans)}跨({best.pattern}){best.spans},梁高 {best.beam_h:.2f}m,"
f"梁片数 {best.num_girders},主筋直径 {best.bar_diameter_mm}mm,"
f"最大利用率 {best.worst_utilization:.2f},混凝土总用量约 "
f"{best.total_concrete_m3:.1f}m³(可行方案中最省)。"
)
return SpanLayoutResult(found=True, best=best, candidates=candidates, message=message)