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
27 return ('%g' % x
).split('e')
30 return np
.float64('1e' + split_number(x
)[1])
35 class AppForm(QMainWindow
):
37 def __init__(self
, parent
=None):
38 QMainWindow
.__init
__(self
, parent
)
39 self
.setWindowTitle(u
'Курсовой проект')
41 self
.create_main_frame()
42 self
.setWindowState(Qt
.WindowMaximized
)
49 def create_main_frame(self
):
50 self
.main_frame
= QWidget()
51 self
.init_work_frame()
52 self
.init_param_frame()
54 self
.splitter
= QSplitter()
55 self
.splitter
.addWidget(self
.param_frame
)
57 self
.splitter
.addWidget(self
.work_frame
)
58 self
.main_layout
= QGridLayout(self
.main_frame
)
59 # self.main_layout.addWidget(self.param_frame, 0, 0)
60 # self.main_layout.addWidget(self.work_frame, 0, 1)
61 self
.main_layout
.addWidget(self
.splitter
)
62 self
.setCentralWidget(self
.main_frame
)
64 def init_param_frame(self
):
65 self
.param_frame
= QWidget()
66 param_group
= QGroupBox(u
"&Параметры")
67 param_layout
= QGridLayout(self
.param_frame
)
68 param_layout
.addWidget(param_group
, 0, 0)
70 self
.edit_LY
= QLineEdit(str(c
.LY
))
71 self
.edit_LY
.setMinimumWidth(40)
72 self
.edit_LZ
= QLineEdit(str(c
.LZ
))
73 self
.edit_LZ
.setMinimumWidth(40)
74 self
.edit_C
= QLineEdit(str(c
.C
))
75 self
.edit_C
.setMinimumWidth(40)
76 self
.edit_LAMBDA
= QLineEdit(str(c
.LAMBDA
))
77 self
.edit_LAMBDA
.setMinimumWidth(40)
78 self
.edit_T
= QLineEdit('1e-14')
79 self
.edit_dim_y
= QLineEdit(str(50))
80 self
.edit_dim_z
= QLineEdit(str(50))
82 pg_layout
= QFormLayout(param_group
)
83 pg_layout
.addRow(u
'Ширина ly', self
.edit_LY
)
84 pg_layout
.addRow(u
'Высота lz', self
.edit_LZ
)
85 pg_layout
.addRow(u
'Скорость C', self
.edit_C
)
86 pg_layout
.addRow(u
'Волна λ', self
.edit_LAMBDA
)
87 pg_layout
.addRow(u
'Момент T', self
.edit_T
)
88 pg_layout
.addRow(u
'Размер по y (I)', self
.edit_dim_y
)
89 pg_layout
.addRow(u
'Размер по z (J)', self
.edit_dim_z
)
90 self
.param_frame
.setMaximumWidth(250)
92 self
.connect(self
.edit_LY
, SIGNAL("returnPressed()"), self
.on_grid_change
)
93 self
.connect(self
.edit_LZ
, SIGNAL("returnPressed()"), self
.on_grid_change
)
94 self
.connect(self
.edit_dim_y
, SIGNAL("returnPressed()"), self
.on_grid_change
)
95 self
.connect(self
.edit_dim_z
, SIGNAL("returnPressed()"), self
.on_grid_change
)
97 def _make_analytic(self
):
98 a_group
= QGroupBox(u
"Аналитическое решение")
99 a_group
.setCheckable(True)
100 a_layout
= QFormLayout(a_group
)
102 self
.edit_length
= QLineEdit(str(500))
103 a_layout
.addRow(u
"Элементов ряда", self
.edit_length
)
104 self
.edit_length
.setMaximumWidth(100)
108 def _make_explicit(self
):
109 e_group
= QGroupBox(u
"Явная схема")
110 e_group
.setCheckable(True)
111 e_group
.setChecked(False)
112 e_layout
= QFormLayout(e_group
)
113 self
.edit_exp_step_t
= QLineEdit()
114 e_layout
.addRow(u
"Шаг по t", self
.edit_exp_step_t
)
118 def _make_implicit(self
):
119 i_group
= QGroupBox(u
"Неявная схема")
120 i_group
.setCheckable(True)
121 i_group
.setChecked(False)
122 i_layout
= QFormLayout(i_group
)
123 self
.edit_imp_step_t
= QLineEdit()
124 i_layout
.addRow(u
"Шаг по t", self
.edit_imp_step_t
)
128 def _make_norm_frame(self
):
129 self
.norm_frame
= QWidget()
130 self
.n_fig
= Figure((5.0, 4.0), dpi
= self
.dpi
)
131 self
.n_canvas
= FigureCanvas(self
.n_fig
)
132 self
.n_canvas
.setParent(self
.main_frame
)
133 self
.n_axes
= self
.n_fig
.add_subplot(111)
134 n_layout
= QGridLayout(self
.norm_frame
)
135 n_layout
.addWidget(self
.n_canvas
, 0, 0, 1, 3)
136 n_toolbar
= NavigationToolbar(self
.n_canvas
, self
.norm_frame
)
137 n_layout
.addWidget(n_toolbar
, 1, 0, 1, 3)
139 ht_button
= QPushButton("test ht")
140 self
.connect(ht_button
, SIGNAL("clicked()"), self
.on_test_ht
)
141 n_layout
.addWidget(ht_button
, 2, 0)
142 hy_button
= QPushButton("test hy")
143 self
.connect(hy_button
, SIGNAL("clicked()"), self
.on_test_hy
)
144 n_layout
.addWidget(hy_button
, 2, 1)
145 hz_button
= QPushButton("test hz")
146 self
.connect(hz_button
, SIGNAL("clicked()"), self
.on_test_hz
)
147 n_layout
.addWidget(hz_button
, 2, 2)
149 def init_work_frame(self
):
150 self
.work_frame
= QTabWidget()
153 self
.z_fig
= Figure((5.0, 4.0), dpi
= self
.dpi
)
154 self
.z_canvas
= FigureCanvas(self
.z_fig
)
155 self
.z_canvas
.setParent(self
.main_frame
)
156 self
.z_axes
= self
.z_fig
.add_subplot(111)
158 self
.graph_frame
= QWidget()
159 graph_layout
= QGridLayout(self
.graph_frame
)
160 graph_layout
.addWidget(self
.z_canvas
, 0, 0, 1, 1)
162 self
.mpl_toolbar
= NavigationToolbar(self
.z_canvas
, self
.graph_frame
)
163 # self.mpl_toolbar.setOrientation(Qt.Vertical)
164 graph_layout
.addWidget(self
.mpl_toolbar
, 1, 0, 1, 1)
166 scheme_frame
= QWidget()
167 scheme_layout
= QGridLayout(scheme_frame
)
168 self
.a_group
= self
._make
_analytic
()
169 self
.exp_group
= self
._make
_explicit
()
170 self
.imp_group
= self
._make
_implicit
()
171 scheme_layout
.addWidget(self
.a_group
, 0, 0, 1, 1)
172 scheme_layout
.addWidget(self
.exp_group
, 0, 1, 1, 1)
173 scheme_layout
.addWidget(self
.imp_group
, 0, 2, 1, 1)
175 self
.button_scheme_run
= QPushButton(u
'Пуск')
176 self
.connect(self
.button_scheme_run
, SIGNAL("clicked()"), self
.on_scheme_run
)
177 self
.button_scheme_run
.setFocus(Qt
.ActiveWindowFocusReason
)
179 graph_layout
.addWidget(scheme_frame
, 2, 0)
180 graph_layout
.addWidget(self
.button_scheme_run
, 3, 0)
182 self
._make
_norm
_frame
()
184 self
.about_frame
= QWidget()
186 self
.work_frame
.addTab(self
.graph_frame
, u
"&Разностная схема")
187 self
.work_frame
.addTab(self
.norm_frame
, u
"&Аппроксимация")
188 # self.work_frame.addTab(self.about_frame, u"&О программе")
190 def on_test_ht(self
):
191 ly_str
= unicode(self
.edit_LY
.text())
192 lz_str
= unicode(self
.edit_LZ
.text())
193 ny_str
= unicode(self
.edit_dim_y
.text())
194 nz_str
= unicode(self
.edit_dim_z
.text())
195 time_str
= unicode(self
.edit_T
.text())
199 ly
= np
.float64(ly_str
)
200 lz
= np
.float64(lz_str
)
205 time
= np
.float64(time_str
)
207 ht_exp
= min(hy
, hz
) / (np
.sqrt(2) * c
.C
)
212 for n
in xrange(1, 5):
215 solver
= ExplicitSolver(ny
, nz
, time
, ht
=ht
)
217 for i
in xrange(u
.shape
[0]):
218 for j
in xrange(u
.shape
[1]):
219 u
[i
, j
] -= Exm(i
* hy
, j
* hz
, time
, M
)
220 y_vals
.append(np
.max(np
.abs(u
)))
223 line
, = self
.n_axes
.plot(x_vals
, y_vals
, 'o-')
225 self
.n_axes
.grid(True)
226 self
.n_axes
.set_xlabel('ht')
227 self
.n_axes
.set_ylabel('err')
230 def on_test_hy(self
):
231 ly_str
= unicode(self
.edit_LY
.text())
232 lz_str
= unicode(self
.edit_LZ
.text())
233 ny_str
= unicode(self
.edit_dim_y
.text())
234 nz_str
= unicode(self
.edit_dim_z
.text())
235 time_str
= unicode(self
.edit_T
.text())
239 ly
= np
.float64(ly_str
)
240 lz
= np
.float64(lz_str
)
245 time
= np
.float64(time_str
)
247 ht_exp
= min(hy
, hz
) / (np
.sqrt(2) * c
.C
)
254 for n
in xrange(1, 11):
257 solver
= ExplicitSolver(ny
, nz
, time
, ht
=ht
)
259 for i
in xrange(u
.shape
[0]):
260 for j
in xrange(u
.shape
[1]):
261 u
[i
, j
] -= Exm(i
* hy
, j
* hz
, time
, M
)
262 y_vals
.append(np
.max(np
.abs(u
)))
266 line
, = self
.n_axes
.plot(x_vals
, y_vals
, 'o-')
268 self
.n_axes
.grid(True)
269 self
.n_axes
.set_xlabel('ht')
270 self
.n_axes
.set_ylabel('err')
273 def on_test_hz(self
):
276 def on_grid_change(self
):
277 ly_str
= unicode(self
.edit_LY
.text())
278 lz_str
= unicode(self
.edit_LZ
.text())
279 ny_str
= unicode(self
.edit_dim_y
.text())
280 nz_str
= unicode(self
.edit_dim_z
.text())
282 ly
= np
.float64(ly_str
)
283 lz
= np
.float64(lz_str
)
288 h_exp
= min(hy
, hz
) / (np
.sqrt(2) * c
.C
)
290 exp_l
= ("%g" % h_exp
).split('e')
291 imp_l
= ("%g" % h_imp
).split('e')
292 ht_exp
= '1e' + exp_l
[1]
293 ht_imp
= str(np
.trunc(np
.float64(imp_l
[0]))) + 'e' + imp_l
[1]
294 self
.edit_exp_step_t
.setText(ht_exp
)
295 self
.edit_imp_step_t
.setText(ht_imp
)
297 def clear_axes(self
, axes
):
301 axes
.set_ylabel('Ex')
303 def test_graph(self
):
304 self
.clear_axes(self
.z_axes
)
308 return int(unicode(self
.edit_length
.text()))
310 def _parse_grid(self
):
311 I
= int(unicode(self
.edit_dim_y
.text()))
312 J
= int(unicode(self
.edit_dim_z
.text()))
315 def _parse_exp(self
):
316 s
= unicode(self
.edit_exp_step_t
.text()).strip()
321 def _parse_imp(self
):
322 s
= unicode(self
.edit_imp_step_t
.text()).strip()
327 def _parse_args(self
):
328 ly
, lz
, c
, lambda_
, t
= [np
.float64(unicode(p
.text()).strip()) \
329 for p
in [self
.edit_LY
, self
.edit_LZ
, self
.edit_C
, self
.edit_LAMBDA
, self
.edit_T
]]
330 return ly
, lz
, c
, lambda_
, t
332 def on_scheme_run(self
):
333 is_analytic
, is_explicit
, is_implicit
= [g
.isChecked() \
334 for g
in [self
.a_group
, self
.exp_group
, self
.imp_group
]]
336 if not (is_analytic
or is_explicit
or is_implicit
):
339 I
, J
= self
._parse
_grid
()
343 if is_explicit
or is_implicit
:
344 exp_ht
= self
._parse
_exp
()
345 imp_ht
= self
._parse
_imp
()
347 ly
, lz
, c
, lambda_
, t
= self
._parse
_args
()
348 self
.data
.z
= np
.linspace(0, lz
, J
+ 1)
350 # self.worker = SolverWorker()
351 # self.connect(worker, SIGNAL("finished()"), self.plot_graphs)
352 # self.connect(worker, SIGNAL("terminated()"), self.plot_graphs)
358 self
.data
.E_a
= [Exm(ly
/ 2, z_
, t
, m
) for z_
in self
.data
.z
]
359 line
, = self
.z_axes
.plot(self
.data
.z
, self
.data
.E_a
, color
='red')
361 legs
.append('Analytical')
363 solver
= ExplicitSolver(I
, J
, t
, exp_ht
)
365 self
.data
.E_exp
= u
[u
.shape
[0] / 2, :]
366 line
, = self
.z_axes
.plot(self
.data
.z
, self
.data
.E_exp
, color
='blue')
368 legs
.append('Explicit scheme')
370 solver
= ImplicitSolver(I
, J
, t
, imp_ht
)
372 self
.data
.E_imp
= u
[u
.shape
[0] / 2, :]
373 line
, = self
.z_axes
.plot(self
.data
.z
, self
.data
.E_imp
, color
='green')
375 legs
.append('Implicit scheme')
376 self
.z_axes
.grid(True)
377 self
.z_axes
.set_xlim(0, max(self
.data
.z
))
378 emax
= max(self
.data
.E_a
)
379 self
.z_axes
.set_ylim(-1.5 * emax
, 1.5 * emax
)
380 self
.z_axes
.set_xlabel('z')
381 self
.z_axes
.set_ylabel('Ex')
382 self
.z_axes
.legend(lines
, legs
)
385 # def on_deviation_run(self):
386 # flags = (is_analytic, is_explicit, is_implicit) = [g.isChecked() \
387 # for g in [self.a_group, self.exp_group, self.imp_group]]
389 # if not (is_analytic or is_explicit or is_implicit):
391 # if len(filter(None, flags)) < 2:
394 # self.d_axes.clear()
397 # if (is_analytic and is_explicit):
398 # self.data.a_exp_dev = np.abs(self.data.E_a - self.data.E_exp)
399 # line, = self.d_axes.plot(self.data.z, self.data.a_exp_dev, color='blue')
401 # legs.append('Analytical and explicit scheme')
402 # if (is_analytic and is_implicit):
403 # self.data.a_imp_dev = np.abs(self.data.E_a - self.data.E_imp)
404 # line, = self.d_axes.plot(self.data.z, self.data.a_imp_dev, color='green')
406 # legs.append('Analytical and implicit scheme')
407 # if (is_explicit and is_implicit):
408 # self.data.exp_imp = np.abs(self.data.E_exp - self.data.E_imp)
409 # line, = self.d_axes.plot(self.data.z, self.data.exp_imp, color='black')
411 # legs.append('Explicit and implicit schemes')
412 # self.d_axes.grid(True)
413 # self.d_axes.set_xlabel('z')
414 # self.d_axes.set_ylabel('e')
415 # emax = max(self.data.E_a)
416 # zmax = self.data.z[-1]
417 # self.d_axes.set_ylim(0, 2*emax)
418 # self.d_axes.set_xlim(0, zmax)
419 # self.d_axes.legend(lines, legs)
420 # self.d_canvas.draw()
423 class SolverWorker(QThread
):
425 def __init__(self
, parent
=None):
426 QThread
.__init
__(self
, parent
)
434 def work(self
, solver
):
435 self
.solver
= solver()