civil-tools-v 0.0.1__py3-none-any.whl → 0.0.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- CivilTools/Const/CAD.py +2 -0
- CivilTools/Const/Concrete.py +144 -0
- CivilTools/Const/Steel.py +21 -0
- CivilTools/Const/__init__.py +3 -0
- CivilTools/DXFGenerator/BasicDXF.py +238 -1
- CivilTools/DXFGenerator/DetailDXF.py +324 -0
- CivilTools/DXFGenerator/DrawingAttribs.py +45 -0
- CivilTools/DXFGenerator/LayerManager.py +37 -0
- CivilTools/DXFGenerator/__init__.py +3 -0
- CivilTools/FigureGenerator/BasicPNGPlotter.py +28 -25
- CivilTools/FigureGenerator/BasicPltPlotter.py +115 -1
- CivilTools/FigureGenerator/SeismicReport/ShearMassRatio.py +73 -0
- CivilTools/FigureGenerator/SeismicReport/ShearMoment.py +71 -0
- CivilTools/FigureGenerator/SeismicReport/__init__.py +2 -0
- CivilTools/FigureGenerator/StairCalculationSheetPNGPlotter.py +2 -8
- CivilTools/ReportGenerator/BasicGenerator.py +109 -83
- CivilTools/ReportGenerator/DocParagraph.py +3 -5
- CivilTools/ReportGenerator/DocPicture.py +7 -8
- CivilTools/ReportGenerator/DocTable.py +11 -11
- CivilTools/ReportGenerator/SeismicReport.py +302 -143
- CivilTools/ReportGenerator/SeismicReportTemplate.py +523 -202
- CivilTools/ReportGenerator/StairCalculationReport.py +249 -185
- CivilTools/ReportGenerator/UtilFunctions.py +108 -104
- CivilTools/ReportGenerator/__init__.py +2 -2
- CivilTools/YDBLoader/BuildingDefine/Beam/Beam.py +12 -15
- CivilTools/YDBLoader/BuildingDefine/Column/Column.py +5 -5
- CivilTools/YDBLoader/BuildingDefine/ComponentType.py +1 -1
- CivilTools/YDBLoader/BuildingDefine/Geometry/Grid.py +8 -12
- CivilTools/YDBLoader/BuildingDefine/Geometry/Joint.py +11 -10
- CivilTools/YDBLoader/BuildingDefine/Geometry/StandFloor.py +1 -1
- CivilTools/YDBLoader/BuildingDefine/GlobalResult/BasicResult.py +44 -24
- CivilTools/YDBLoader/BuildingDefine/GlobalResult/SeismicResult.py +168 -54
- CivilTools/YDBLoader/BuildingDefine/Section/Section.py +26 -31
- CivilTools/YDBLoader/BuildingDefine/Section/ShapeEnum.py +9 -9
- CivilTools/YDBLoader/BuildingDefine/Slab/Slab.py +1 -1
- CivilTools/YDBLoader/BuildingDefine/StairPart/LoadDefine.py +16 -10
- CivilTools/YDBLoader/BuildingDefine/StairPart/StairComponent.py +41 -37
- CivilTools/YDBLoader/BuildingDefine/StairPart/StairPart.py +133 -78
- CivilTools/YDBLoader/SQLiteConnector/Connector.py +16 -8
- CivilTools/YDBLoader/SQLiteConnector/RowDataFactory.py +19 -17
- CivilTools/YDBLoader/SQLiteConnector/YDBTableName.py +31 -20
- CivilTools/YDBLoader/YDBLoader.py +128 -110
- {civil_tools_v-0.0.1.dist-info → civil_tools_v-0.0.3.dist-info}/METADATA +88 -5
- civil_tools_v-0.0.3.dist-info/RECORD +60 -0
- {civil_tools_v-0.0.1.dist-info → civil_tools_v-0.0.3.dist-info}/WHEEL +1 -1
- civil_tools_v-0.0.1.dist-info/RECORD +0 -50
- {civil_tools_v-0.0.1.dist-info → civil_tools_v-0.0.3.dist-info}/LICENSE +0 -0
- {civil_tools_v-0.0.1.dist-info → civil_tools_v-0.0.3.dist-info}/top_level.txt +0 -0
@@ -3,78 +3,183 @@ import abc
|
|
3
3
|
from typing import List
|
4
4
|
import matplotlib.pyplot as plt
|
5
5
|
|
6
|
+
|
6
7
|
class SinglePeriod:
|
7
|
-
"""单个周期
|
8
|
-
|
8
|
+
"""单个周期"""
|
9
|
+
|
9
10
|
def __init__(
|
10
|
-
self,
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
11
|
+
self,
|
12
|
+
index: int,
|
13
|
+
time: float,
|
14
|
+
angle: float = 0,
|
15
|
+
coeff_x: float = 1,
|
16
|
+
coeff_y: float = 0,
|
17
|
+
coeff_z: float = 0,
|
18
|
+
mass_particpate_x: float = 0,
|
19
|
+
mass_particpate_y: float = 0,
|
20
|
+
mass_particpate_z: float = 0,
|
19
21
|
):
|
20
22
|
self.index = index
|
21
23
|
self.time = time
|
22
24
|
self.angle = angle
|
23
|
-
assert
|
24
|
-
|
25
|
-
|
25
|
+
assert (
|
26
|
+
abs(coeff_x + coeff_y + coeff_z - 1) < 0.01
|
27
|
+
), "The sum of three participite coeff should == 1"
|
26
28
|
self.coeff_x = coeff_x
|
27
29
|
self.coeff_y = coeff_y
|
28
30
|
self.coeff_z = coeff_z
|
31
|
+
if coeff_x >= coeff_y and coeff_x >= coeff_z:
|
32
|
+
self.direction = "X"
|
33
|
+
elif coeff_y >= coeff_x and coeff_y >= coeff_z:
|
34
|
+
self.direction = "Y"
|
35
|
+
else:
|
36
|
+
self.direction = "Z"
|
29
37
|
self.mass_participate_x = mass_particpate_x
|
30
38
|
self.mass_participate_y = mass_particpate_y
|
31
39
|
self.mass_participate_z = mass_particpate_z
|
32
|
-
|
40
|
+
|
41
|
+
@property
|
42
|
+
def time_str(self):
|
43
|
+
return f"{self.time:.4f}"
|
44
|
+
|
45
|
+
@property
|
46
|
+
def movement_coeff(self):
|
47
|
+
return (
|
48
|
+
f"{self.coeff_x + self.coeff_y:.2f} ({self.coeff_x:.2f}+{self.coeff_y:.2f})"
|
49
|
+
)
|
50
|
+
|
51
|
+
@property
|
52
|
+
def rotation_coeff(self):
|
53
|
+
return f"{self.coeff_z:.2f}"
|
54
|
+
|
55
|
+
def get_mass_participate_x(self, last):
|
56
|
+
return f"{self.mass_participate_x*100:.1f} ({(self.mass_participate_x + last)*100:.1f})"
|
57
|
+
|
58
|
+
def get_mass_participate_y(self, last):
|
59
|
+
return f"{self.mass_participate_y*100:.1f} ({(self.mass_participate_y + last)*100:.1f})"
|
60
|
+
|
33
61
|
def __str__(self):
|
34
|
-
return f"T{self.index}:\t{self.time:.4f}s\t[X:{self.coeff_x*100:.1f}%;\tY:{self.coeff_y*100:.1f}%;\tZ:{self.coeff_z*100:.1f}%]"
|
35
|
-
|
62
|
+
return f"T{self.index}:\t{self.time:.4f}s\t[X:{self.coeff_x*100:.1f}%;\tY:{self.coeff_y*100:.1f}%;\tZ:{self.coeff_z*100:.1f}%]"
|
63
|
+
|
36
64
|
def __repr__(self):
|
37
|
-
return str(self)
|
65
|
+
return str(self)
|
66
|
+
|
67
|
+
def to_json(self):
|
68
|
+
return {"index": self.index, "time": self.time}
|
69
|
+
|
38
70
|
|
39
71
|
class Period:
|
40
|
-
def __init__(self,periods:List[SinglePeriod]
|
72
|
+
def __init__(self, periods: List[SinglePeriod], model_type=None):
|
73
|
+
if len(periods) < 3:
|
74
|
+
raise ValueError("At least three periods is needed.")
|
41
75
|
self.periods = periods
|
42
|
-
|
76
|
+
|
43
77
|
def __str__(self):
|
44
|
-
if len(self.periods)<=10:
|
78
|
+
if len(self.periods) <= 10:
|
45
79
|
return "\n".join([str(period) for period in self.periods])
|
46
80
|
else:
|
47
81
|
result = "\n".join([str(period) for period in self.periods[:9]])
|
48
82
|
result += "\n....\n"
|
49
83
|
result += str(self.periods[-1])
|
50
84
|
return result
|
51
|
-
|
85
|
+
|
52
86
|
def __repr__(self):
|
53
87
|
return self.__str__()
|
54
|
-
|
88
|
+
|
89
|
+
@classmethod
|
90
|
+
def mock_data(
|
91
|
+
cls, order: str = "xyz", num: int = 40, mass_participate: float = 0.95
|
92
|
+
):
|
93
|
+
single_period_list = []
|
94
|
+
single_period_list.append(
|
95
|
+
SinglePeriod(
|
96
|
+
1,
|
97
|
+
2.5,
|
98
|
+
0,
|
99
|
+
order[0] == "x",
|
100
|
+
order[0] == "y",
|
101
|
+
order[0] == "z",
|
102
|
+
0.1,
|
103
|
+
0.1,
|
104
|
+
0.1,
|
105
|
+
)
|
106
|
+
)
|
107
|
+
single_period_list.append(
|
108
|
+
SinglePeriod(
|
109
|
+
2,
|
110
|
+
2.0,
|
111
|
+
0,
|
112
|
+
order[1] == "x",
|
113
|
+
order[1] == "y",
|
114
|
+
order[1] == "z",
|
115
|
+
0.2,
|
116
|
+
0.2,
|
117
|
+
0.2,
|
118
|
+
)
|
119
|
+
)
|
120
|
+
single_period_list.append(
|
121
|
+
SinglePeriod(
|
122
|
+
3,
|
123
|
+
1.5,
|
124
|
+
0,
|
125
|
+
order[2] == "x",
|
126
|
+
order[2] == "y",
|
127
|
+
order[2] == "z",
|
128
|
+
0.3,
|
129
|
+
0.3,
|
130
|
+
0.3,
|
131
|
+
)
|
132
|
+
)
|
133
|
+
|
134
|
+
for i in range(num - 3):
|
135
|
+
single_period_list.append(
|
136
|
+
SinglePeriod(
|
137
|
+
i + 4,
|
138
|
+
0.5 - 0.01 * i,
|
139
|
+
0,
|
140
|
+
1,
|
141
|
+
0,
|
142
|
+
0,
|
143
|
+
mass_participate,
|
144
|
+
mass_participate,
|
145
|
+
mass_participate,
|
146
|
+
)
|
147
|
+
)
|
148
|
+
return Period(single_period_list)
|
149
|
+
|
150
|
+
def to_json(self):
|
151
|
+
return {"periods": [i.to_json() for i in self.periods]}
|
152
|
+
|
153
|
+
|
55
154
|
class ValuePeer:
|
56
|
-
def __init__(self, x:float, y:float):
|
155
|
+
def __init__(self, x: float, y: float):
|
57
156
|
self.x = x
|
58
157
|
self.y = y
|
158
|
+
|
59
159
|
def __str__(self):
|
60
|
-
if self.x >500:
|
160
|
+
if self.x > 500:
|
61
161
|
return f"X:{self.x:.1f}\tY:{self.y:.1f}"
|
62
|
-
elif self.x >5:
|
162
|
+
elif self.x > 5:
|
63
163
|
return f"X:{self.x:.2f}\tY:{self.y:.2f}"
|
64
164
|
else:
|
65
165
|
return f"X:{self.x:.3f}\tY:{self.y:.3f}"
|
66
|
-
|
166
|
+
|
167
|
+
def to_json(self):
|
168
|
+
return {"X": self.x, "Y": self.y}
|
169
|
+
|
170
|
+
|
67
171
|
class FloorSeismicResult:
|
68
|
-
def __init__(
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
172
|
+
def __init__(
|
173
|
+
self,
|
174
|
+
floor_num: int,
|
175
|
+
tower_num: int,
|
176
|
+
force: ValuePeer = None,
|
177
|
+
shear: ValuePeer = None,
|
178
|
+
moment: ValuePeer = None,
|
179
|
+
disp: ValuePeer = None,
|
180
|
+
stiffness: ValuePeer = None,
|
181
|
+
shear_capacity: ValuePeer = None,
|
182
|
+
):
|
78
183
|
self.floor_num = floor_num
|
79
184
|
self.tower_num = tower_num
|
80
185
|
self.force = force
|
@@ -83,46 +188,55 @@ class FloorSeismicResult:
|
|
83
188
|
self.disp = disp
|
84
189
|
self.stiffness = stiffness
|
85
190
|
self.shear_capacity = shear_capacity
|
86
|
-
|
191
|
+
|
87
192
|
def __str__(self):
|
88
193
|
return f"Flr.{self.floor_num}:Fx={self.force.x};Fy={self.force.y}"
|
89
194
|
|
90
195
|
def __repr__(self):
|
91
196
|
return self.__str__()
|
92
197
|
|
198
|
+
def to_json(self):
|
199
|
+
return {
|
200
|
+
"floor_num": self.floor_num,
|
201
|
+
"tower_num": self.tower_num,
|
202
|
+
"shear": self.shear.to_json(),
|
203
|
+
}
|
204
|
+
|
205
|
+
|
93
206
|
class SeismicResult:
|
94
|
-
def __init__(self,
|
95
|
-
floor_result : List[FloorSeismicResult]
|
96
|
-
):
|
207
|
+
def __init__(self, floor_result: List[FloorSeismicResult]):
|
97
208
|
self.floor_result = floor_result
|
98
|
-
|
209
|
+
|
99
210
|
@property
|
100
211
|
def seismic_shear_x(self):
|
101
212
|
return [i.shear.x for i in self.floor_result]
|
102
|
-
|
213
|
+
|
103
214
|
@property
|
104
215
|
def floor_index(self):
|
105
|
-
return [i+1 for i in range(len(self.floor_result))]
|
106
|
-
|
216
|
+
return [i + 1 for i in range(len(self.floor_result))]
|
217
|
+
|
107
218
|
def plot_shear(self):
|
108
|
-
fig,ax = plt.subplots(figsize=(2,5))
|
109
|
-
ax.plot(self.seismic_shear_x,self.floor_index)
|
110
|
-
return fig,ax
|
111
|
-
|
219
|
+
fig, ax = plt.subplots(figsize=(2, 5))
|
220
|
+
ax.plot(self.seismic_shear_x, self.floor_index)
|
221
|
+
return fig, ax
|
222
|
+
|
112
223
|
def __str__(self):
|
113
224
|
result = f"Total floor: {len(self.floor_result)}\n"
|
114
225
|
for temp_result in self.floor_result:
|
115
226
|
result += str(temp_result)
|
116
227
|
result += "\n"
|
117
228
|
return result
|
118
|
-
|
229
|
+
|
119
230
|
def __repr__(self):
|
120
231
|
return self.__str__()
|
121
|
-
|
122
|
-
|
232
|
+
|
233
|
+
def to_json(self):
|
234
|
+
return {"floor_result": [i.to_json() for i in self.floor_result]}
|
235
|
+
|
236
|
+
|
123
237
|
if __name__ == "__main__":
|
124
238
|
p_list = []
|
125
239
|
for i in range(112):
|
126
|
-
p_list.append(SinglePeriod(i+1,i*0.1+0.1,0,1-i*0.1,i*0.1,0))
|
240
|
+
p_list.append(SinglePeriod(i + 1, i * 0.1 + 0.1, 0, 1 - i * 0.1, i * 0.1, 0))
|
127
241
|
P = Period(p_list)
|
128
|
-
print(str(P))
|
242
|
+
print(str(P))
|
@@ -1,49 +1,44 @@
|
|
1
1
|
from .ShapeEnum import ShapeEnum
|
2
2
|
from typing import List
|
3
3
|
|
4
|
+
|
4
5
|
class Section:
|
5
|
-
def __init__(self,
|
6
|
-
id:int,
|
7
|
-
k:ShapeEnum,
|
8
|
-
vals:List[float],
|
9
|
-
mat:int = 1
|
10
|
-
):
|
6
|
+
def __init__(self, id: int, k: ShapeEnum, vals: List[float], mat: int = 1):
|
11
7
|
self.id = id
|
12
8
|
self.k = k
|
13
9
|
self.mat = mat
|
14
10
|
value_number = len(vals)
|
15
|
-
self.b = vals[0] if value_number>=1 else None
|
16
|
-
self.h = vals[1] if value_number>=2 else None
|
17
|
-
self.u = vals[2] if value_number>=3 else None
|
18
|
-
self.t = vals[3] if value_number>=4 else None
|
19
|
-
self.d = vals[4] if value_number>=5 else None
|
20
|
-
self.f = vals[5] if value_number>=6 else None
|
21
|
-
|
11
|
+
self.b = vals[0] if value_number >= 1 else None
|
12
|
+
self.h = vals[1] if value_number >= 2 else None
|
13
|
+
self.u = vals[2] if value_number >= 3 else None
|
14
|
+
self.t = vals[3] if value_number >= 4 else None
|
15
|
+
self.d = vals[4] if value_number >= 5 else None
|
16
|
+
self.f = vals[5] if value_number >= 6 else None
|
22
17
|
|
23
18
|
def __str__(self):
|
24
|
-
|
19
|
+
"""todo:这里需要完善str方法"""
|
25
20
|
display_function = {
|
26
|
-
ShapeEnum.Rect
|
27
|
-
ShapeEnum.HShape
|
28
|
-
ShapeEnum.Circle
|
29
|
-
ShapeEnum.RegularPolygon
|
30
|
-
ShapeEnum.Groove
|
31
|
-
ShapeEnum.Cross
|
32
|
-
ShapeEnum.Box
|
33
|
-
ShapeEnum.CircleTube
|
34
|
-
ShapeEnum.CircleCFT
|
35
|
-
ShapeEnum.HSRC
|
36
|
-
ShapeEnum.BoxSRC
|
37
|
-
ShapeEnum.CrossSRC
|
38
|
-
|
39
|
-
ShapeEnum.UnKnown : lambda : f"Unknown:{self.b}"
|
21
|
+
ShapeEnum.Rect: lambda: f"Rect-{self.b}mmx{self.h}mm",
|
22
|
+
ShapeEnum.HShape: lambda: f"{self.b}",
|
23
|
+
ShapeEnum.Circle: lambda: f"Circle-Diameter:{self.b}mm",
|
24
|
+
ShapeEnum.RegularPolygon: lambda: f"{self.b}",
|
25
|
+
ShapeEnum.Groove: lambda: f"{self.b}",
|
26
|
+
ShapeEnum.Cross: lambda: f"{self.b}",
|
27
|
+
ShapeEnum.Box: lambda: f"{self.b}",
|
28
|
+
ShapeEnum.CircleTube: lambda: f"{self.b}",
|
29
|
+
ShapeEnum.CircleCFT: lambda: f"{self.b}",
|
30
|
+
ShapeEnum.HSRC: lambda: f"{self.b}",
|
31
|
+
ShapeEnum.BoxSRC: lambda: f"{self.b}",
|
32
|
+
ShapeEnum.CrossSRC: lambda: f"{self.b}",
|
33
|
+
ShapeEnum.UnKnown: lambda: f"Unknown:{self.b}",
|
40
34
|
}
|
41
35
|
return display_function[self.k]()
|
42
|
-
|
36
|
+
|
43
37
|
def __repr__(self):
|
44
38
|
return self.__str__()
|
45
39
|
|
40
|
+
|
46
41
|
if __name__ == "__main__":
|
47
|
-
s = Section(1,ShapeEnum.Circle,[20,32])
|
42
|
+
s = Section(1, ShapeEnum.Circle, [20, 32])
|
48
43
|
|
49
|
-
print(s)
|
44
|
+
print(s)
|
@@ -1,5 +1,7 @@
|
|
1
1
|
from enum import Enum
|
2
2
|
import warnings
|
3
|
+
|
4
|
+
|
3
5
|
class ShapeEnum(Enum):
|
4
6
|
# 矩形
|
5
7
|
Rect = 1
|
@@ -25,18 +27,16 @@ class ShapeEnum(Enum):
|
|
25
27
|
BoxSRC = 14
|
26
28
|
# 十字劲
|
27
29
|
CrossSRC = 15
|
28
|
-
|
30
|
+
|
29
31
|
# 未知截面均归于这个类别
|
30
32
|
UnKnown = 999
|
31
|
-
|
33
|
+
|
32
34
|
@classmethod
|
33
|
-
def ConvertToShapeEnum(cls,index:int):
|
34
|
-
try:
|
35
|
+
def ConvertToShapeEnum(cls, index: int):
|
36
|
+
try:
|
35
37
|
return (ShapeEnum)(index)
|
36
38
|
except ValueError:
|
37
|
-
warnings.warn(
|
39
|
+
warnings.warn(
|
40
|
+
f"Shape kind ${index} is not supported yet. It will be converted to UnKnown."
|
41
|
+
)
|
38
42
|
return ShapeEnum.UnKnown
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
@@ -1,2 +1,2 @@
|
|
1
1
|
class Slab:
|
2
|
-
pass
|
2
|
+
pass
|
@@ -1,5 +1,6 @@
|
|
1
1
|
from enum import Enum
|
2
2
|
|
3
|
+
|
3
4
|
class LoadParams:
|
4
5
|
def __init__(self):
|
5
6
|
self.append_dead_load = 1
|
@@ -8,31 +9,36 @@ class LoadParams:
|
|
8
9
|
self.live_load_coef = 1.5
|
9
10
|
self.live_load_adjust_coef = 1
|
10
11
|
self.live_load_permenent_coef = 0.5
|
11
|
-
|
12
|
+
|
13
|
+
|
12
14
|
class LoadType(Enum):
|
13
15
|
Dead = 1
|
14
16
|
Live = 2
|
15
|
-
|
17
|
+
|
18
|
+
|
16
19
|
class LoadCalulateType(Enum):
|
17
20
|
qk = 1
|
18
21
|
q = 2
|
19
22
|
qe = 3
|
20
|
-
|
23
|
+
|
24
|
+
|
21
25
|
class StairLoad:
|
22
|
-
def __init__(self, dead, live, load_params:LoadParams):
|
26
|
+
def __init__(self, dead, live, load_params: LoadParams):
|
23
27
|
self.dead = dead
|
24
28
|
self.live = live
|
25
29
|
self.load_params = load_params
|
26
|
-
|
30
|
+
|
27
31
|
@property
|
28
32
|
def qk(self):
|
29
33
|
return self.dead + self.live
|
30
|
-
|
34
|
+
|
31
35
|
@property
|
32
36
|
def q(self):
|
33
|
-
return
|
34
|
-
|
37
|
+
return (
|
38
|
+
self.load_params.dead_load_coef * self.dead
|
39
|
+
+ self.load_params.live_load_coef * self.live
|
40
|
+
)
|
41
|
+
|
35
42
|
@property
|
36
43
|
def qe(self):
|
37
|
-
return self.dead + self.load_params.live_load_permenent_coef* self.live
|
38
|
-
|
44
|
+
return self.dead + self.load_params.live_load_permenent_coef * self.live
|
@@ -1,40 +1,47 @@
|
|
1
1
|
import math
|
2
2
|
import numpy as np
|
3
3
|
|
4
|
+
|
4
5
|
class Component:
|
5
|
-
|
6
|
+
|
6
7
|
def init_attr(self):
|
7
8
|
self.E = 30000
|
8
9
|
self.B = 1000
|
9
10
|
self.H = 150
|
10
11
|
self.vertical_q = 10
|
11
|
-
self.length = math.sqrt(
|
12
|
+
self.length = math.sqrt(
|
13
|
+
(self.end_point[1] - self.start_point[1]) ** 2
|
14
|
+
+ (self.end_point[0] - self.start_point[0]) ** 2
|
15
|
+
)
|
12
16
|
if self.start_point[0] == self.end_point[0]:
|
13
17
|
self.alpha = 0
|
14
18
|
else:
|
15
|
-
self.alpha = math.atan(
|
16
|
-
|
17
|
-
|
19
|
+
self.alpha = math.atan(
|
20
|
+
(self.end_point[1] - self.start_point[1])
|
21
|
+
/ (self.end_point[0] - self.start_point[0])
|
22
|
+
)
|
23
|
+
|
24
|
+
def __init__(self, p1, p2) -> None:
|
18
25
|
self.start_point = p1
|
19
26
|
self.end_point = p2
|
20
27
|
self.section_kind = "Rectangle"
|
21
28
|
self.init_attr()
|
22
|
-
|
23
|
-
def set_comp_attr(self,e,b,h):
|
29
|
+
|
30
|
+
def set_comp_attr(self, e, b, h):
|
24
31
|
self.E = e
|
25
32
|
self.B = b
|
26
33
|
self.H = h
|
27
|
-
|
34
|
+
|
28
35
|
def set_vertical_q(self, q):
|
29
36
|
self.vertical_q = q
|
30
|
-
|
37
|
+
|
31
38
|
def create_k(self):
|
32
39
|
self.calculate_section_attr()
|
33
|
-
K = np.zeros((6,6))
|
34
|
-
|
40
|
+
K = np.zeros((6, 6))
|
41
|
+
|
35
42
|
l = self.length
|
36
|
-
i = self.E *self.I / l
|
37
|
-
B =
|
43
|
+
i = self.E * self.I / l
|
44
|
+
B = self.E * self.area / l
|
38
45
|
c_x = math.cos(self.alpha)
|
39
46
|
c_y = math.sin(self.alpha)
|
40
47
|
a1 = B * c_x * c_x + 12 * i / l / l * c_y * c_y
|
@@ -56,40 +63,37 @@ class Component:
|
|
56
63
|
K[2, 2] = K[5, 5] = a6
|
57
64
|
K[2, 5] = K[5, 2] = a6 / 2
|
58
65
|
return K
|
59
|
-
|
66
|
+
|
60
67
|
def create_f(self):
|
61
|
-
F = np.zeros((6,1))
|
68
|
+
F = np.zeros((6, 1))
|
62
69
|
# 这里只针对竖向荷载
|
63
70
|
length = abs(self.end_point[0] - self.start_point[0])
|
64
|
-
|
65
|
-
F[1,0] = -self.vertical_q * length / 2
|
66
|
-
F[2,0] = -self.vertical_q * length
|
67
|
-
F[4,0] = -self.vertical_q * length / 2
|
68
|
-
F[5,0] = self.vertical_q * length
|
71
|
+
|
72
|
+
F[1, 0] = -self.vertical_q * length / 2
|
73
|
+
F[2, 0] = -self.vertical_q * length**2 / 12
|
74
|
+
F[4, 0] = -self.vertical_q * length / 2
|
75
|
+
F[5, 0] = self.vertical_q * length**2 / 12
|
69
76
|
return F
|
70
|
-
|
77
|
+
|
71
78
|
def calculate_section_attr(self):
|
72
79
|
if self.section_kind == "Rectangle":
|
73
|
-
self.I = self.B * self.H
|
80
|
+
self.I = self.B * self.H**3 / 12
|
74
81
|
self.area = self.B * self.H
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
self.
|
79
|
-
self.
|
80
|
-
self.
|
81
|
-
|
82
|
-
|
82
|
+
|
83
|
+
def set_f(self, f_1_x, f_1_y, f_2_x, f_2_y):
|
84
|
+
self.f_1_x = f_1_x / 1e3
|
85
|
+
self.f_1_y = f_1_y / 1e3
|
86
|
+
self.f_2_x = f_2_x / 1e3
|
87
|
+
self.f_2_y = f_2_y / 1e3
|
88
|
+
|
83
89
|
def set_m(self, m_1, m_2):
|
84
|
-
self.m_1 = m_1/1e6
|
85
|
-
self.m_2 = m_2/1e6
|
86
|
-
|
90
|
+
self.m_1 = m_1 / 1e6
|
91
|
+
self.m_2 = m_2 / 1e6
|
87
92
|
|
88
93
|
@property
|
89
94
|
def v1(self):
|
90
|
-
return self.f_1_y*np.cos(self.alpha) - self.f_1_x*np.sin(self.alpha)
|
91
|
-
|
95
|
+
return self.f_1_y * np.cos(self.alpha) - self.f_1_x * np.sin(self.alpha)
|
96
|
+
|
92
97
|
@property
|
93
98
|
def v2(self):
|
94
|
-
return -self.f_2_y*np.cos(self.alpha) + self.f_2_x*np.sin(self.alpha)
|
95
|
-
|
99
|
+
return -self.f_2_y * np.cos(self.alpha) + self.f_2_x * np.sin(self.alpha)
|