git reimport

This commit is contained in:
2019-03-15 13:50:21 +04:00
commit 5c01c4d176
6 changed files with 296 additions and 0 deletions

11
Pipfile Normal file
View File

@@ -0,0 +1,11 @@
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"
[packages]
[dev-packages]
[requires]
python_version = "3.7"

BIN
float_roots.pickle Normal file

Binary file not shown.

BIN
saved_roots_1000.pickle Normal file

Binary file not shown.

Binary file not shown.

171
src/app.py Normal file
View File

@@ -0,0 +1,171 @@
import sys
from PyQt5.QtWidgets import QApplication, QGridLayout, QGroupBox, QLabel, QLineEdit, QMessageBox, QPushButton, \
QSizePolicy, QVBoxLayout, QWidget
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
import solver
class App(QWidget):
def __init__(self):
super().__init__()
self.solver = solver.Solver()
self.grid = QGridLayout()
self.setLayout(self.grid)
self.resize(1200, 600)
self.plot = PlotCanvas(width=10, height=4)
self.grid.addWidget(self.plot, 1, 1, 1, 1)
param_box = QGroupBox()
param_vbox = QVBoxLayout()
param_vbox.addWidget(QLabel('Длина цилиндра l'))
self.l_field = QLineEdit('20')
self.l_field.setStyleSheet("color: black;")
param_vbox.addWidget(self.l_field)
param_vbox.addWidget(QLabel('Коэффициент диффузии D'))
self.D_field = QLineEdit('0.6')
self.D_field.setStyleSheet("color: black;")
param_vbox.addWidget(self.D_field)
param_vbox.addWidget(QLabel('Мембранный коэффициент диффузии H'))
self.H_field = QLineEdit('4')
self.H_field.setStyleSheet("color: black;")
param_vbox.addWidget(self.H_field)
param_vbox.addWidget(QLabel('Момент времени t'))
self.t_field = QLineEdit('0')
self.t_field.setStyleSheet("color: black;")
param_vbox.addWidget(self.t_field)
param_vbox.addWidget(QLabel('Точность поиска собственных значений'))
self.eps_field = QLineEdit('1e-9')
self.eps_field.setStyleSheet("color: black;")
param_vbox.addWidget(self.eps_field)
param_vbox.addWidget(QLabel('Количество членов ряда в суммировании'))
self.sum_count_field = QLineEdit('100')
self.sum_count_field.setStyleSheet("color: black;")
param_vbox.addWidget(self.sum_count_field)
calc_button = QPushButton('Рассчитать')
calc_button.pressed.connect(self.calc)
param_vbox.addWidget(calc_button)
param_vbox.addStretch(1)
param_box.setLayout(param_vbox)
self.grid.addWidget(param_box, 1, 2, 1, 1)
self.calc()
def show_error(self, text):
msg = QMessageBox()
msg.setIcon(QMessageBox.Information)
msg.setText(text)
msg.setWindowTitle("Ошибка расчетов")
msg.setStandardButtons(QMessageBox.Ok)
msg.exec_()
def calc(self):
try:
l_str = self.l_field.text()
l_val = float(l_str)
except Exception as e:
self.show_error(f'Некорректный формат числа: {l_str}')
return
try:
D_str = self.D_field.text()
D_val = float(D_str)
except Exception as e:
self.show_error(f'Некорректный формат числа: {D_str}')
return
try:
H_str = self.H_field.text()
H_val = float(H_str)
except Exception as e:
self.show_error(f'Некорректный формат числа: {H_str}')
return
try:
t_str = self.t_field.text()
t_val = float(t_str)
except Exception as e:
self.show_error(f'Некорректный формат числа: {t_str}')
return
try:
eps_str = self.eps_field.text()
eps_val = float(eps_str)
except Exception as e:
self.show_error(f'Некорректный формат числа: {eps_str}')
return
try:
sum_count_str = self.sum_count_field.text()
sum_count_val = int(sum_count_str)
except Exception as e:
self.show_error(f'Некорректный формат числа: {sum_count_str}')
return
if not (
1e-3 <= l_val <= 1e+3 and
1e-3 <= D_val <= 1e+3 and
1e-3 <= H_val <= 1e+3 and
0 <= t_val <= 1e+3 and
1e-20 <= eps_val <= 1e+3 and
1 <= sum_count_val <= 1e+3
):
self.show_error(f'Некорректные входные данные')
return
self.solver.set_params(l_val, D_val, H_val, t_val, eps_val, sum_count_val)
plot_x, plot_y = self.solver.calc()
self.plot.plot(plot_x, plot_y)
class PlotCanvas(FigureCanvas):
def __init__(self, parent=None, width=4, height=4, dpi=100):
fig = Figure(figsize=(width, height), dpi=dpi)
self.axes = fig.add_subplot(111)
FigureCanvas.__init__(self, fig)
self.setParent(parent)
FigureCanvas.setSizePolicy(self, QSizePolicy.Expanding, QSizePolicy.Expanding)
FigureCanvas.updateGeometry(self)
def plot(self, plot_x, plot_y):
self.axes.clear()
self.axes.plot(plot_x, plot_y)
self.axes.set_xlabel('$x, \\mathrm{м}$')
self.axes.set_ylabel('$u$')
self.axes.set_title('Поле концентрации вещества в цилиндре, $\\frac{\\mathrm{кг}}{\\mathrm{м}^3}$')
self.axes.set_ylim(0, None)
self.axes.grid(True)
self.draw()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = App()
ex.show()
sys.exit(app.exec_())

114
src/solver.py Normal file
View File

@@ -0,0 +1,114 @@
import datetime
import pickle
import numpy as np
class Solver:
def __init__(self):
self.l = None
self.D = None
self.H = None
self.t = None
self.eps = 1e-9
self.sum_count = 100
self.alphas = np.zeros(0)
def find_root(self, index):
C = self.H * self.l / 2
l = np.pi * index + self.eps
r = np.pi * index + np.pi / 2 - self.eps
while True:
m = (l + r) / 2
val = np.tan(m) - C / m
if abs(val) < self.eps or abs(r - l) < self.eps:
return m
if val > 0:
r = m
else:
l = m
def set_params(self, l, D, H, t, eps, sum_count):
self.l = l
self.D = D
self.H = H
self.t = t
self.eps = eps
self.sum_count = sum_count
self.alphas = np.array([self.find_root(i) for i in range(self.sum_count)])
def calc(self):
plot_x = np.linspace(0, self.l, 1000)
start_dt = datetime.datetime.utcnow()
plot_y = np.array([self.calc_single(x) for x in plot_x])
end_dt = datetime.datetime.utcnow()
print((end_dt - start_dt) / 1000)
return plot_x, plot_y
# noinspection PyTypeChecker
def calc_single(self, x: float) -> float:
if self.l is None:
raise ValueError('Not initialized')
# @formatter:off
return np.sum(
(
-4 * np.pi ** 2 * (
self.H * self.l * np.sin(2 * self.alphas * x / self.l)
+ 2 * self.alphas * np.cos(2 * self.alphas * x / self.l)
) * (
-self.H * self.l * np.cos(2 * self.alphas)
+ self.H * self.l
+ 2 * self.alphas * np.sin(2 * self.alphas)
) * np.exp(
-4 * self.D * self.alphas ** 2 * self.t / self.l ** 2
) / (
5 * (
self.alphas ** 2
- np.pi ** 2
) * (
4 * self.H ** 2 * self.alphas * self.l ** 2
- self.H ** 2 * self.l ** 2 * np.sin(4 * self.alphas)
- 4 * self.H * self.alphas * self.l * (np.cos(4 * self.alphas) - 1)
+ 4 * self.alphas ** 2 * (
4 * self.alphas
+ np.sin(4 * self.alphas)
)
)
)
)
)
# @formatter:on
with open('float_roots.pickle', 'rb') as file:
float_roots = pickle.load(file)
def u_elem(x, t, alpha_n):
return -4 * np.pi ** 2 * (alpha_n * np.cos(alpha_n * x / 10) + 40 * np.sin(alpha_n * x / 10)) * (
alpha_n * np.sin(2 * alpha_n) - 40 * np.cos(2 * alpha_n) + 40) * np.exp(-3 * alpha_n ** 2 * t / 500) / (
5 * (alpha_n ** 2 - np.pi ** 2) * (alpha_n ** 2 * (4 * alpha_n + np.sin(4 * alpha_n)) - 80 * alpha_n * (
np.cos(4 * alpha_n) - 1) + 6400 * alpha_n - 1600 * np.sin(4 * alpha_n)))
def u(x, t):
return np.sum(u_elem(x, t, float_roots))
if __name__ == '__main__':
solver = Solver()
solver.set_params(20, 0.6, 4, 10)
print(solver.calc(10))