Uploaded by skidanovaanna33

Отчёт лаб.1

advertisement
МИНИСТЕРСТВО НАУКИ И ВЫСШЕГО ОБРАЗОВАНИЯ
РОССИЙСКОЙ ФЕДЕРАЦИИ
Федеральное государственное автономное образовательное
учреждение высшего образования
«Самарский национальный исследовательский университет
имени академика С.П. Королева»
(Самарский университет)
Институт информатики и кибернетики
Кафедра технической кибернетики
Отчет по
Лабораторной работе № 1
по курсу
Параллельные алгоритмы
Группа 6132-010402D
Студент ________________________________ А.Р. Скиданова
(подпись)
Преподаватель __________________________ Д.Л. Головашкин
(подпись)
Самара 2022
Задание
Реализовать алгоритм решения двумерной задачи теплопроводности
через явную разностную схему.
Задача задаётся следующей системой уравнений:
ut = a 2 (u xx + u yy ) + q (t )
0  x  Lx , 0  y  Ly ;

u (0, x, y ) =  ( x, y );

ut (t , x, 0) = 0, ut (t , x, Ly ) = 0, t  0;
u (t , 0, y ) = T , u (t , L , y ) = T , t  0,
n
x
s

(1)
где t – время, x – координата по оси X, y – координата по оси Y, a –
коэффициент теплопроводности.
Для построения явной схемы определим равномерную сетку как
множество узлов:
xi = ihx , i  0, I1 , hx =
y j = jhy ,
Lx
;
I1
j  0, I 2 , hy =
tk = k , k  0, K ,  =
Ly
I2
;
T
,
K
где 𝐼1 – число разбиений по X, 𝐼2 – число разбиений по Y, K – число
разбиений по времени.
Теперь заменим функции непрерывных аргументов в уравнении (1) на
их сеточные аналоги, тогда значение функции u для каждого последующего
временного слоя будет вычисляться из предыдущего следующим образом:
uik, +j 1 = (1 − 21 − 22 )uik, j + 1 (uik+1, j + uik−1, j ) + 2 (uik, j +1 + uik, j −1 ) ,
где 1 =  / hx2 , 2 = / hy2 .
2
Эксперимент
1. Цель эксперимента
Целью эксперимента является проверка правильности реализованного
алгоритма для решения двумерной задачи теплопроводности с помощью
явной разностной схемы. Для этого необходимо проверить сходимость
полученного решения к аналитическому.
2. Выбор программно-аппаратной базы.
Для написания кода выбран язык Python c интерпретатором версии 3.8.
Это высокоуровневый язык программирования общего назначения, с
динамической строгой типизацией и автоматическим управлением памятью.
Основной упор в Python делается на скорости написания кода, а не на скорости
его выполнения, как например в языках С и C++. Поэтому этот язык удобно
использовать там, где нужно быстро написать что-то работающее. А так как
основной задачей данного эксперимента является проверка корректности
решения, а не проверка скорости его выполнения, то он хорошо подходит для
этих целей. Для работы с Python выбрана среда PyCharm.
Используемый компьютер имеет следующие показатели:
Операционная система – Windows 10;
Процессор – Intel Core i5-1135G7;
Оперативная память – 16,0 Гб;
Количество ядер – 4;
Количество логических процессоров – 8.
Код программы представлен в приложение А.
3. Выбор параметров эксперимента
Для упрощения расчётов для системы (1) было решено установить
следующие значения:
Коэффициент теплопроводности a =1;
Границы: 0  x   , 0  y   , 0  t  1 ;
3
Начальное условие  ( x, y ) = sin( x) sin( y ) ;
Граничные условия u (t , 0, y ) = 0, u (t , Lx , y) = 0 .
Аналитическое
решение
u (t , x, y ) = sin( x) sin( y )e −2t .
будет
рассчитываться
по
формуле:
Так же важными параметрами являются мелкость разбиения по осям и
мелкость разбиения по времени. Для проведения эксперимента будут
использоваться сетки следующих размеров: 20×20, 40×40, 80×80, 140×140,
200×200, 260×260. Это поможет рассмотреть сходимость при изменении шага
дискретизации.
Значение K будет рассчитываться в соответствии с условием
устойчивости:

2
x
h
+

hy2
 0.5 ,
где ℎ𝑥 – шаг по x, ℎ𝑦 – шаг по y, τ – шаг по времени.
4. Теоретическое предсказание результатов экспериментов
При проверке сходимости разностного решения к аналитическому
ожидается, что при уменьшении мелкости разбиения, численное решение
будет сходиться к аналитическому, что означает – с увеличением количества
узлов, погрешность будет уменьшаться.
5. Проведение эксперимента
Для проверки сходимости запустим программу для сеток заданного
размера, и посчитаем погрешность между численным решением и
аналитическим на последнем временном слое (Таблица 1). Визуализация
результатов на рисунке 1.
Таблица 1
Размер
сетки
20×20
40×40
80×80
140×140
200×200
260×260
Значение
1.860067 6.243436 1.482690 4.737352 2.301318 1.355416
погрешнос e-04
e-05
e-05
e-06
e-06
e-06
ти
4
Рисунок 1 – Погрешность численного решения при увеличении количества
узлов
Так же можно графически продемонстрировать сходимость
зафиксировав два показателя из трех. Например, для случая 40×40 рассмотреть
последний слой при x=20 (рисунок 2).
(а)
(б)
Рисунок 2 – (a) Графическое представление сходимости решения к явному
решению, (б) приближение полученного графика
6. Анализ результатов
Из рисунка 2 видно, что графики буквально накладываются друг на
друга, что доказывает, как минимум визуальную сходимость полученного
решения.
5
График 1 показывает довольно быструю сходимость полученного
решения к аналитическому. Видно, что с увеличением количества разбиений
уменьшается погрешность, и достигается большая точность.
7. Соответствие теоретическим ожиданиям
В результате работы видно, что практические результаты совпали с
теоретическими ожиданиями.
8. Выводы
Таким образом можно сделать вывод, что поставленные цели
достигнуты. Численно и графически показано, что алгоритм работает верно,
разностное решение сходится к аналитическому и показывает достаточный
уровень точности.
6
ПРИЛОЖЕНИЕ А
Код программы
import numpy as np
import matplotlib.pylab as plt
import math
import time
def my_u(Lx, Ly, T, I1, I2):
K = I1 * 2
ht = (T / K)
hx = Lx / (I1 - 1)
hy = Ly / (I2 - 1)
while ((ht / (hx * hx) + ht / (hy * hy)) > 0.5):
K=K+1
ht = T / K
print(K)
lambda1 = ht / (hx ** 2)
lambda2 = ht / (hy ** 2)
c1 = 1 - 2 * lambda1 - 2 * lambda2
u = np.zeros((I1, I2), dtype=np.float64)
u_new = np.zeros((I1, I2), dtype=np.float64)
for i in range(0, I1):
for j in range(0, I2):
u[i, j] = math.sin((i * hx)) * math.sin((j * hy))
one = time.time()
for k in range(1, K):
if (k % 2 == 1):
for i in range(1, I1 - 1):
for j in range(1, I2 - 1):
u_new[i, j] = u[i, j] * c1 + lambda1 * (u[i + 1, j] + u[i - 1, j]) + lambda2 * (
u[i, j + 1] + u[i, j - 1])
else:
for i in range(1, I1 - 1):
for j in range(1, I2 - 1):
u[i, j] = u_new[i, j] * c1 + lambda1 * (u_new[i + 1, j] + u_new[i - 1, j]) + lambda2 * (
u_new[i, j + 1] + u_new[i, j - 1])
two = time.time()
print("Real Time ", two - one)
if (K % 2 == 0):
return u_new, K
else:
return u, K
def a_solution2(K, I1, I2, T, nt):
t = np.linspace(0, T, K + 1, endpoint=True)
x = np.linspace(0, np.pi, I1, endpoint=True)
y = np.linspace(0, np.pi, I2, endpoint=True)
u = np.zeros((I1, I2), dtype=np.float64)
for i in range(u.shape[0]):
for j in range(u.shape[1]):
7
u[i, j] = np.sin((x[i])) * np.sin((y[j])) * math.exp((-2) * t[nt])
return u
def main():
I1 = 40
I2 = 40
T=1
# Решение - схема
U, K = my_u(np.pi, np.pi, T, I1, I2)
# Аналитическое решение
UA2 = a_solution2(K, I1, I2, T, K)
x = np.linspace(0, np.pi, I1, endpoint=True)
y = np.linspace(0, np.pi, I2, endpoint=True)
ax = plt.subplot()
ax.set_title("Сходимость")
ax.plot(x, U[20, :], color="blue")
ax.plot(x, UA2[20, :], color="red")
plt.legend(['Явная схема', 'Аналитическое решение'])
plt.xlabel('y', color='gray')
plt.ylabel('t', color='gray')
ax.grid()
print('My', U[14, :])
print('My', UA2[14, :])
sum = 0;
for i in range(1, I1 - 1):
for j in range(1, I2 - 1):
sum = sum + abs(U[i, j] - UA2[i, j])
print("pp", sum / ((I1 - 2) * (I2 - 2)))
plt.show()
if __name__ == '__main__':
main()
8
Download