git reimport
This commit is contained in:
11
Pipfile
Normal file
11
Pipfile
Normal 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
BIN
float_roots.pickle
Normal file
Binary file not shown.
BIN
saved_roots_1000.pickle
Normal file
BIN
saved_roots_1000.pickle
Normal file
Binary file not shown.
BIN
src/__pycache__/solver.cpython-37.pyc
Normal file
BIN
src/__pycache__/solver.cpython-37.pyc
Normal file
Binary file not shown.
171
src/app.py
Normal file
171
src/app.py
Normal 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
114
src/solver.py
Normal 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))
|
Reference in New Issue
Block a user