3 # Политика префиксов в именах
6 # QPushButton - button_
11 from PyQt4
.QtCore
import *
12 from PyQt4
.QtGui
import *
15 from matplotlib
.backends
.backend_qt4agg
import FigureCanvasQTAgg
as FigureCanvas
16 from matplotlib
.backends
.backend_qt4agg
import NavigationToolbar2QTAgg
as NavigationToolbar
17 from matplotlib
.figure
import Figure
21 from grid
import ExplicitSolver
, ImplicitSolver
, norm
23 from waves
import Exm
, setParameters
25 from third
import Exm
, setParameters
30 return ('%g' % x
).split('e')
33 return np
.float64('1e' + split_number(x
)[1])
38 class AppForm(QMainWindow
):
40 def __init__(self
, parent
=None):
41 QMainWindow
.__init
__(self
, parent
)
42 self
.setWindowTitle(u
'Курсовой проект')
44 self
.create_main_frame()
45 self
.setWindowState(Qt
.WindowMaximized
)
52 def create_main_frame(self
):
53 self
.main_frame
= QWidget()
54 self
.init_work_frame()
55 self
.init_param_frame()
57 self
.splitter
= QSplitter()
58 self
.splitter
.addWidget(self
.param_frame
)
60 self
.splitter
.addWidget(self
.work_frame
)
61 self
.main_layout
= QGridLayout(self
.main_frame
)
62 # self.main_layout.addWidget(self.param_frame, 0, 0)
63 # self.main_layout.addWidget(self.work_frame, 0, 1)
64 self
.main_layout
.addWidget(self
.splitter
)
65 self
.setCentralWidget(self
.main_frame
)
67 def init_param_frame(self
):
68 self
.param_frame
= QWidget()
69 param_group
= QGroupBox(u
"&Параметры")
70 param_layout
= QGridLayout(self
.param_frame
)
71 param_layout
.addWidget(param_group
, 0, 0)
73 self
.edit_LY
= QLineEdit(str(co
.LY
))
74 self
.edit_LY
.setMinimumWidth(40)
75 self
.edit_LZ
= QLineEdit(str(co
.LZ
))
76 self
.edit_LZ
.setMinimumWidth(40)
77 self
.edit_C
= QLineEdit(str(co
.C
))
78 self
.edit_C
.setMinimumWidth(40)
79 self
.edit_LAMBDA
= QLineEdit(str(co
.LAMBDA
))
80 self
.edit_LAMBDA
.setMinimumWidth(40)
81 self
.edit_T
= QLineEdit('1e-14')
82 self
.edit_dim_y
= QLineEdit(str(50))
83 self
.edit_dim_z
= QLineEdit(str(50))
85 pg_layout
= QFormLayout(param_group
)
86 pg_layout
.addRow(u
'Ширина ly', self
.edit_LY
)
87 pg_layout
.addRow(u
'Высота lz', self
.edit_LZ
)
88 pg_layout
.addRow(u
'Скорость C', self
.edit_C
)
89 pg_layout
.addRow(u
'Волна λ', self
.edit_LAMBDA
)
90 pg_layout
.addRow(u
'Момент T', self
.edit_T
)
91 pg_layout
.addRow(u
'Размер по y (I)', self
.edit_dim_y
)
92 pg_layout
.addRow(u
'Размер по z (J)', self
.edit_dim_z
)
93 self
.param_frame
.setMaximumWidth(250)
95 self
.connect(self
.edit_LY
, SIGNAL("returnPressed()"), self
.on_grid_change
)
96 self
.connect(self
.edit_LZ
, SIGNAL("returnPressed()"), self
.on_grid_change
)
97 self
.connect(self
.edit_dim_y
, SIGNAL("returnPressed()"), self
.on_grid_change
)
98 self
.connect(self
.edit_dim_z
, SIGNAL("returnPressed()"), self
.on_grid_change
)
100 def _make_analytic(self
):
101 a_group
= QGroupBox(u
"Аналитическое решение")
102 a_group
.setCheckable(True)
103 a_layout
= QFormLayout(a_group
)
105 self
.edit_length
= QLineEdit(str(500))
106 a_layout
.addRow(u
"Элементов ряда", self
.edit_length
)
107 self
.edit_length
.setMaximumWidth(100)
111 def _make_explicit(self
):
112 e_group
= QGroupBox(u
"Явная схема")
113 e_group
.setCheckable(True)
114 e_group
.setChecked(False)
115 e_layout
= QFormLayout(e_group
)
116 self
.edit_exp_step_t
= QLineEdit()
117 e_layout
.addRow(u
"Шаг по t", self
.edit_exp_step_t
)
121 def _make_implicit(self
):
122 i_group
= QGroupBox(u
"Неявная схема")
123 i_group
.setCheckable(True)
124 i_group
.setChecked(False)
125 i_layout
= QFormLayout(i_group
)
126 self
.edit_imp_step_t
= QLineEdit()
127 i_layout
.addRow(u
"Шаг по t", self
.edit_imp_step_t
)
131 def _make_norm_frame(self
):
132 self
.norm_frame
= QWidget()
133 self
.n_fig
= Figure((5.0, 4.0), dpi
= self
.dpi
)
134 self
.n_canvas
= FigureCanvas(self
.n_fig
)
135 self
.n_canvas
.setParent(self
.main_frame
)
136 self
.n_axes
= self
.n_fig
.add_subplot(111)
137 n_layout
= QGridLayout(self
.norm_frame
)
138 n_layout
.addWidget(self
.n_canvas
, 0, 0, 1, 3)
139 n_toolbar
= NavigationToolbar(self
.n_canvas
, self
.norm_frame
)
140 n_layout
.addWidget(n_toolbar
, 1, 0, 1, 3)
142 ht_button
= QPushButton("test ht")
143 self
.connect(ht_button
, SIGNAL("clicked()"), self
.on_test_ht
)
144 n_layout
.addWidget(ht_button
, 2, 0)
145 hy_button
= QPushButton("test hy")
146 self
.connect(hy_button
, SIGNAL("clicked()"), self
.on_test_hy
)
147 n_layout
.addWidget(hy_button
, 2, 1)
148 hz_button
= QPushButton("test hz")
149 self
.connect(hz_button
, SIGNAL("clicked()"), self
.on_test_hz
)
150 n_layout
.addWidget(hz_button
, 2, 2)
152 def init_work_frame(self
):
153 self
.work_frame
= QTabWidget()
156 self
.z_fig
= Figure((5.0, 4.0), dpi
= self
.dpi
)
157 self
.z_canvas
= FigureCanvas(self
.z_fig
)
158 self
.z_canvas
.setParent(self
.main_frame
)
159 self
.z_axes
= self
.z_fig
.add_subplot(111)
161 self
.graph_frame
= QWidget()
162 graph_layout
= QGridLayout(self
.graph_frame
)
163 graph_layout
.addWidget(self
.z_canvas
, 0, 0, 1, 1)
165 self
.mpl_toolbar
= NavigationToolbar(self
.z_canvas
, self
.graph_frame
)
166 # self.mpl_toolbar.setOrientation(Qt.Vertical)
167 graph_layout
.addWidget(self
.mpl_toolbar
, 1, 0, 1, 1)
169 scheme_frame
= QWidget()
170 scheme_layout
= QGridLayout(scheme_frame
)
171 self
.a_group
= self
._make
_analytic
()
172 self
.exp_group
= self
._make
_explicit
()
173 self
.imp_group
= self
._make
_implicit
()
174 scheme_layout
.addWidget(self
.a_group
, 0, 0, 1, 1)
175 scheme_layout
.addWidget(self
.exp_group
, 0, 1, 1, 1)
176 scheme_layout
.addWidget(self
.imp_group
, 0, 2, 1, 1)
178 self
.button_scheme_run
= QPushButton(u
'Пуск')
179 self
.connect(self
.button_scheme_run
, SIGNAL("clicked()"), self
.on_scheme_run
)
180 self
.button_scheme_run
.setFocus(Qt
.ActiveWindowFocusReason
)
182 graph_layout
.addWidget(scheme_frame
, 2, 0)
183 graph_layout
.addWidget(self
.button_scheme_run
, 3, 0)
185 self
._make
_norm
_frame
()
187 self
.about_frame
= QWidget()
189 self
.work_frame
.addTab(self
.graph_frame
, u
"&Разностная схема")
190 self
.work_frame
.addTab(self
.norm_frame
, u
"&Аппроксимация")
191 # self.work_frame.addTab(self.about_frame, u"&О программе")
193 def on_test_ht(self
):
194 ly_str
= unicode(self
.edit_LY
.text())
195 lz_str
= unicode(self
.edit_LZ
.text())
196 ny_str
= unicode(self
.edit_dim_y
.text())
197 nz_str
= unicode(self
.edit_dim_z
.text())
198 time_str
= unicode(self
.edit_T
.text())
202 ly
= np
.float64(ly_str
)
203 lz
= np
.float64(lz_str
)
208 time
= np
.float64(time_str
)
210 ht_exp
= min(hy
, hz
) / (np
.sqrt(2) * co
.C
)
215 for n
in xrange(1, 5):
218 solver
= ExplicitSolver(ny
, nz
, time
, ht
=ht
)
220 for i
in xrange(u
.shape
[0]):
221 for j
in xrange(u
.shape
[1]):
222 u
[i
, j
] -= Exm(i
* hy
, j
* hz
, time
, M
)
223 y_vals
.append(np
.max(np
.abs(u
)))
226 line
, = self
.n_axes
.plot(x_vals
, y_vals
, 'o-')
228 self
.n_axes
.grid(True)
229 self
.n_axes
.set_xlabel('ht')
230 self
.n_axes
.set_ylabel('err')
233 def on_test_hy(self
):
234 ly_str
= unicode(self
.edit_LY
.text())
235 lz_str
= unicode(self
.edit_LZ
.text())
236 ny_str
= unicode(self
.edit_dim_y
.text())
237 nz_str
= unicode(self
.edit_dim_z
.text())
238 time_str
= unicode(self
.edit_T
.text())
242 ly
= np
.float64(ly_str
)
243 lz
= np
.float64(lz_str
)
248 time
= np
.float64(time_str
)
250 ht_exp
= min(hy
, hz
) / (np
.sqrt(2) * co
.C
)
257 for n
in xrange(1, 11):
260 solver
= ExplicitSolver(ny
, nz
, time
, ht
=ht
)
262 for i
in xrange(u
.shape
[0]):
263 for j
in xrange(u
.shape
[1]):
264 u
[i
, j
] -= Exm(i
* hy
, j
* hz
, time
, M
)
265 y_vals
.append(np
.max(np
.abs(u
)))
269 line
, = self
.n_axes
.plot(x_vals
, y_vals
, 'o-')
271 self
.n_axes
.grid(True)
272 self
.n_axes
.set_xlabel('ht')
273 self
.n_axes
.set_ylabel('err')
276 def on_test_hz(self
):
279 def on_grid_change(self
):
280 ly_str
= unicode(self
.edit_LY
.text())
281 lz_str
= unicode(self
.edit_LZ
.text())
282 ny_str
= unicode(self
.edit_dim_y
.text())
283 nz_str
= unicode(self
.edit_dim_z
.text())
285 ly
= np
.float64(ly_str
)
286 lz
= np
.float64(lz_str
)
291 h_exp
= min(hy
, hz
) / (np
.sqrt(2) * co
.C
)
293 exp_l
= ("%g" % h_exp
).split('e')
294 imp_l
= ("%g" % h_imp
).split('e')
295 ht_exp
= '1e' + exp_l
[1]
296 ht_imp
= str(np
.trunc(np
.float64(imp_l
[0]))) + 'e' + imp_l
[1]
297 self
.edit_exp_step_t
.setText(ht_exp
)
298 self
.edit_imp_step_t
.setText(ht_imp
)
300 def clear_axes(self
, axes
):
304 axes
.set_ylabel('Ex')
306 def test_graph(self
):
307 self
.clear_axes(self
.z_axes
)
311 return int(unicode(self
.edit_length
.text()))
313 def _parse_grid(self
):
314 I
= int(unicode(self
.edit_dim_y
.text()))
315 J
= int(unicode(self
.edit_dim_z
.text()))
318 def _parse_exp(self
):
319 s
= unicode(self
.edit_exp_step_t
.text()).strip()
324 def _parse_imp(self
):
325 s
= unicode(self
.edit_imp_step_t
.text()).strip()
330 def _parse_args(self
):
331 ly
, lz
, c
, lambda_
, t
= [np
.float64(unicode(p
.text()).strip()) \
332 for p
in [self
.edit_LY
, self
.edit_LZ
, self
.edit_C
, self
.edit_LAMBDA
, self
.edit_T
]]
333 return ly
, lz
, c
, lambda_
, t
335 def on_scheme_run(self
):
336 is_analytic
, is_explicit
, is_implicit
= [g
.isChecked() \
337 for g
in [self
.a_group
, self
.exp_group
, self
.imp_group
]]
339 if not (is_analytic
or is_explicit
or is_implicit
):
342 I
, J
= self
._parse
_grid
()
344 exp_ht
, imp_ht
= None, None
348 if is_explicit
or is_implicit
:
349 exp_ht
= self
._parse
_exp
()
350 imp_ht
= self
._parse
_imp
()
352 ly
, lz
, c
, lambda_
, t
= self
._parse
_args
()
354 if exp_ht
is not None:
355 if not co
.test_exp_stable(ly
/I
, lz
/J
, exp_ht
):
356 warn
= QMessageBox
.warning(
359 u
'С такими параметрами система может быть неустойчива!<br />Вы уверены, что хотите продолжить?',
360 QMessageBox
.Yes | QMessageBox
.No
)
362 if imp_ht
is not None:
363 if not co
.test_imp_stable(ly
/I
, imp_ht
):
364 warn
= QMessageBox
.warning(
367 u
'С такими параметрами система может быть неустойчива!<br />Вы уверены, что хотите продолжить?',
368 QMessageBox
.Yes | QMessageBox
.No
)
371 self
.data
.z
= np
.linspace(0, lz
, J
+ 1)
377 setParameters(ly
, lz
, c
, _lambda
)
378 self
.data
.E_a
= [Exm(ly
/ 2, z_
, t
, m
) for z_
in self
.data
.z
]
379 line
, = self
.z_axes
.plot(self
.data
.z
, self
.data
.E_a
, color
='red')
381 legs
.append('Analytical')
383 solver
= ExplicitSolver(I
, J
, t
, exp_ht
)
385 self
.data
.E_exp
= u
[u
.shape
[0] / 2, :]
386 line
, = self
.z_axes
.plot(self
.data
.z
, self
.data
.E_exp
, color
='blue')
388 legs
.append('Explicit scheme')
390 solver
= ImplicitSolver(I
, J
, t
, imp_ht
)
392 self
.data
.E_imp
= u
[u
.shape
[0] / 2, :]
393 line
, = self
.z_axes
.plot(self
.data
.z
, self
.data
.E_imp
, color
='green')
395 legs
.append('Implicit scheme')
396 self
.z_axes
.grid(True)
397 self
.z_axes
.set_xlim(0, max(self
.data
.z
))
398 emax
= max(self
.data
.E_a
)
399 self
.z_axes
.set_ylim(-1.5 * emax
, 1.5 * emax
)
400 self
.z_axes
.set_xlabel('z')
401 self
.z_axes
.set_ylabel('Ex')
402 self
.z_axes
.legend(lines
, legs
)
405 # def on_deviation_run(self):
406 # flags = (is_analytic, is_explicit, is_implicit) = [g.isChecked() \
407 # for g in [self.a_group, self.exp_group, self.imp_group]]
409 # if not (is_analytic or is_explicit or is_implicit):
411 # if len(filter(None, flags)) < 2:
414 # self.d_axes.clear()
417 # if (is_analytic and is_explicit):
418 # self.data.a_exp_dev = np.abs(self.data.E_a - self.data.E_exp)
419 # line, = self.d_axes.plot(self.data.z, self.data.a_exp_dev, color='blue')
421 # legs.append('Analytical and explicit scheme')
422 # if (is_analytic and is_implicit):
423 # self.data.a_imp_dev = np.abs(self.data.E_a - self.data.E_imp)
424 # line, = self.d_axes.plot(self.data.z, self.data.a_imp_dev, color='green')
426 # legs.append('Analytical and implicit scheme')
427 # if (is_explicit and is_implicit):
428 # self.data.exp_imp = np.abs(self.data.E_exp - self.data.E_imp)
429 # line, = self.d_axes.plot(self.data.z, self.data.exp_imp, color='black')
431 # legs.append('Explicit and implicit schemes')
432 # self.d_axes.grid(True)
433 # self.d_axes.set_xlabel('z')
434 # self.d_axes.set_ylabel('e')
435 # emax = max(self.data.E_a)
436 # zmax = self.data.z[-1]
437 # self.d_axes.set_ylim(0, 2*emax)
438 # self.d_axes.set_xlim(0, zmax)
439 # self.d_axes.legend(lines, legs)
440 # self.d_canvas.draw()
443 class SolverWorker(QThread
):
445 def __init__(self
, parent
=None):
446 QThread
.__init
__(self
, parent
)
454 def work(self
, solver
):
455 self
.solver
= solver()