This repository has been archived by the owner on May 13, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
beam.py
123 lines (95 loc) · 3.98 KB
/
beam.py
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
121
122
123
import math
import sys
import matplotlib.pyplot as plt
import beam_vtk as bvtk
from PyQt5 import QtWidgets
from MainWindow import MainWindow
import Settings
class Main:
def __init__(self):
self.__current_function = None
self.__current_function_params = []
def set_current_function(self, function, default_params=[]):
self.__current_function = function
self.__current_function_params = default_params
def set_function_param(self, param_index, value):
try:
self.__current_function_params[param_index] = value
except IndexError:
print("Did not set param: param_index not in param array")
return
def eval_current_function(self, x_val, time):
try:
if len(self.__current_function_params) <= 0:
return self.__current_function(x_val, time)
return self.__current_function(x_val, time, self.__current_function_params)
except:
print("INVALID FUNCTION")
return 0
def eval_func_for_xvals(self, x_vals, time):
return_vals = []
for x in x_vals:
return_vals.append(self.eval_current_function(x, time))
return return_vals
@staticmethod
def displacement(mode, x):
beta = math.pi * mode
r = beta * x
try:
k = (math.cos(beta) + math.cosh(beta) / (math.sin(beta) + math.sinh(beta)))
displacement = math.cosh(r) - math.cos(r) + k * (math.sin(r) - math.sinh(r))
return displacement
except ZeroDivisionError:
return 0.0
@staticmethod
# Params list is [mode, omega]
def beam_deflection(x_val, time, params):
return Main.displacement(params[0], x_val / Settings.x_vals[-1]) * math.sin(params[1] * time)
@staticmethod
def generate_plot(t, x):
for i, time in enumerate(t):
y = Settings.shared_main.eval_func_for_xvals(Settings.x_vals, t)
plt.figure(1)
if i == 3:
plt.plot(x, y, 'bo-')
else:
plt.plot(x, y, 'k-', alpha=0.1)
plt.xlabel('x distance on beam')
plt.ylabel('y(x,t) displacement')
plt.grid(True)
plt.show(block=False)
@staticmethod
def get_active_camera(ren_window):
ren_window.GetRenderers().GetFirstRenderer().GetActiveCamera()
@staticmethod
def generate_vtk(x):
N = len(x)
N -= 1
app = QtWidgets.QApplication(sys.argv)
Settings.main_window = MainWindow()
Settings.shared_main.set_current_function(Main.beam_deflection, [Settings.mode, Settings.omega])
# bvtk.Node and bvtk.Line are custom objects to make reuse of mappings/actors
# convenient and less messy.
Settings.nodes = [bvtk.Node() for i in range(N)]
y = Settings.shared_main.eval_func_for_xvals(Settings.x_vals, 10) # grabbing an arbitrary time to create deflected beam state
for i in range(N):
if i < (N - 1):
# Updates position ahead of time to render next node height
Settings.nodes[i + 1].update_position(x[i + 1], y[i + 1], 0)
next_node = Settings.nodes[i + 1]
else:
next_node = Settings.nodes[i - 1]
# Generates all node specific actors and adds to renderer
Settings.nodes[i].add_poly_actor_to_renderer(Settings.main_window.renderer, next_node, x[i], y[i])
Settings.main_window.ren_window.Render()
Settings.update_slot = bvtk.vtkUpdate(Settings.main_window, 0)
Settings.main_window.add_slot(Settings.update_slot)
Settings.timer.timeout.connect(Settings.update_slot.execute)
Settings.timer.start(50)
# Sign up to receive TimerEvent
Settings.main_window.reset_camera_position()
#main_window.renderer.SetActiveCamera(Settings.camera)
sys.exit(app.exec_())
if __name__ == "__main__":
# generate_plot(t_vals, x_vals)
Main.generate_vtk(Settings.x_vals)