Some changes with approx
[pde-python.git] / gui.py
blobd9a9231ede17f99b80bd9b05f29e4472564a971d
1 #-*- coding: utf-8
3 # Политика префиксов в именах
4 # QLineEdit - edit_
5 # QLabel - label_
6 # QPushButton - button_
9 import sys
11 from PyQt4.QtCore import *
12 from PyQt4.QtGui import *
14 import matplotlib
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
19 import numpy as np
21 from grid import ExplicitSolver, ImplicitSolver, norm
22 from waves import Exm
23 import const as c
26 def split_number(x):
27 return ('%g' % x).split('e')
29 def normal(x):
30 return np.float64('1e' + split_number(x)[1])
32 class Dummy(object):
33 pass
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)
44 self.on_grid_change()
46 self.data = Dummy()
47 # self.test_graph()
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)
106 return a_group
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)
116 return e_group
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)
126 return i_group
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()
152 self.dpi = 100
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())
197 M = 600
199 ly = np.float64(ly_str)
200 lz = np.float64(lz_str)
201 ny = int(ny_str)
202 nz = int(nz_str)
203 hy = (ly / ny)
204 hz = (lz / nz)
205 time = np.float64(time_str)
207 ht_exp = min(hy, hz) / (np.sqrt(2) * c.C)
208 ht = normal(ht_exp)
210 x_vals = []
211 y_vals = []
212 for n in xrange(1, 5):
213 print ht
214 x_vals.append(ht)
215 solver = ExplicitSolver(ny, nz, time, ht=ht)
216 u = solver.solve()
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)))
221 ht /= 2
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')
228 self.n_canvas.draw()
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())
237 M = 600
239 ly = np.float64(ly_str)
240 lz = np.float64(lz_str)
241 ny = int(ny_str)
242 nz = int(nz_str)
243 hy = (ly / ny)
244 hz = (lz / nz)
245 time = np.float64(time_str)
247 ht_exp = min(hy, hz) / (np.sqrt(2) * c.C)
248 ht = normal(ht_exp)
249 ht /= 2
251 x_vals = []
252 y_vals = []
253 hy_step = hy
254 for n in xrange(1, 11):
255 print hy
256 x_vals.append(hy)
257 solver = ExplicitSolver(ny, nz, time, ht=ht)
258 u = solver.solve()
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)))
263 hy /= 2
264 ny *= 2
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')
271 self.n_canvas.draw()
273 def on_test_hz(self):
274 pass
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)
284 ny = int(ny_str)
285 nz = int(nz_str)
286 hy = (ly / ny)
287 hz = (lz / nz)
288 h_exp = min(hy, hz) / (np.sqrt(2) * c.C)
289 h_imp = hy / 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):
298 axes.clear()
299 axes.grid(True)
300 axes.set_xlabel('z')
301 axes.set_ylabel('Ex')
303 def test_graph(self):
304 self.clear_axes(self.z_axes)
305 self.z_canvas.draw()
307 def _parse_a(self):
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()))
313 return I, J
315 def _parse_exp(self):
316 s = unicode(self.edit_exp_step_t.text()).strip()
317 if s == '':
318 return None
319 return np.float64(s)
321 def _parse_imp(self):
322 s = unicode(self.edit_imp_step_t.text()).strip()
323 if s == '':
324 return None
325 return np.float64(s)
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):
337 return
339 I, J = self._parse_grid()
341 if is_analytic:
342 m = self._parse_a()
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)
354 self.z_axes.clear()
355 lines = []
356 legs = []
357 if is_analytic:
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')
360 lines.append(line)
361 legs.append('Analytical')
362 if is_explicit:
363 solver = ExplicitSolver(I, J, t, exp_ht)
364 u = solver.solve()
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')
367 lines.append(line)
368 legs.append('Explicit scheme')
369 if is_implicit:
370 solver = ImplicitSolver(I, J, t, imp_ht)
371 u = solver.solve()
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')
374 lines.append(line)
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)
383 self.z_canvas.draw()
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):
390 # return
391 # if len(filter(None, flags)) < 2:
392 # return
394 # self.d_axes.clear()
395 # lines = []
396 # legs = []
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')
400 # lines.append(line)
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')
405 # lines.append(line)
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')
410 # lines.append(line)
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)
427 self.exiting = False
428 self.u = None
430 def __del__(self):
431 self.exiting = True
432 self.wait()
434 def work(self, solver):
435 self.solver = solver()
436 self.start()
438 def run(self):
439 u = solver.solve()