Одномерное уравнение теплопроводности. Буй Ван Шань. 6 курс — различия между версиями

Материал из Department of Theoretical and Applied Mechanics
Перейти к: навигация, поиск
(Задание)
(Ссылки для скачивания)
 
(не показаны 83 промежуточные версии 2 участников)
Строка 1: Строка 1:
==Задание==
+
==Постановка задачи==
Решение краевой задачи для одномерного уравнения теплопроводности
+
[[File:Heat eqn.gif|thumb|Пример численного решения уравнения теплопроводности. Цветом и высотой поверхности передана температура данной точки.]]
dU/dt-d2U/dx2=f(x,t), a<x<b, 0<t<Tk
+
Решается однородное [https://ru.wikipedia.org/wiki/%D0%A3%D1%80%D0%B0%D0%B2%D0%BD%D0%B5%D0%BD%D0%B8%D0%B5_%D1%82%D0%B5%D0%BF%D0%BB%D0%BE%D0%BF%D1%80%D0%BE%D0%B2%D0%BE%D0%B4%D0%BD%D0%BE%D1%81%D1%82%D0%B8 уравнение теплопроводности] на промежутке <math>\left[a\ldots b\right]</math>
Начальное условие U(x,0)=U0(x)
+
:<math>\frac{\partial U\left(x,t\right)}{\partial t} - k^2\frac{\partial^2 U\left(x,t\right)}{\partial x^2} = f(x,t)</math>
Конечные условия U(a,t)=M1(t); U(b,t)=M2(t);
+
С граничными условиями
Где f(x,t), U0(x), M1(t), M2(t) - Заданные функции
+
:<math> \begin{cases}
* Заданы: U(x,0)=cos(x+0,48);
+
  U(a,t) = M1(t) \\
          U(0,t)=6t+0,887;
+
  U(b,t) = M2(t)
          U(1,t)=0,0907
+
\end{cases}</math>
          0<x<1;0<t<1
+
и начальным распределением температуры
==Релизация MPI==
+
:<math>U(x,0) = U0(x)</math>
# include <cstdlib>
+
*Где :<math>f(x,t), U0(x), M1(t), M2(t)</math> - Известные функции
# include <iostream>
 
# include <fstream>
 
# include <math.h>
 
# include <time.h>
 
# include "mpi.h"
 
using namespace std;
 
double initial_condition ( double x, double time );
 
double boundary_condition ( double time,int flag);
 
clock_t start,finish;
 
int main(int argv, char** argc)
 
{
 
int my_id,p; //p:  number of processes; my_id: id- process id
 
MPI_Init(&argv,&argc);
 
MPI_Comm_rank(MPI_COMM_WORLD, &my_id);  /* get current process id */
 
    MPI_Comm_size(MPI_COMM_WORLD, &p);    /* get number of processes */
 
if(my_id==0) // Start recording time
 
{
 
start=clock();
 
}
 
double x_min=0; //левый предел
 
double x_max=1; // right limit
 
double t_min=0; // starting time
 
double t_max=1; // ending time
 
double shagt=0.0000001; // time step
 
int ShagovPoT=(t_max-t_min)/shagt;
 
double shagx=0.0001;    // space step
 
int i_shagov=(x_max-x_min)/p/shagx;
 
  
double *T,*Tn;
+
==Реализация==
double *X;
+
===Конечно-разностная схема===
ofstream  myFile,infoFile;
+
[[File:Zavnuischeme.PNG|thumb|300px|Явная разностная схема|right]]
char file_name[100];
+
Задача содержит производную по времени первого порядка и производную по пространственной координате второго порядка.
sprintf(file_name, "result%i.txt", my_id); //file_name
+
Запишем исходное уравнение в виде
+
:<math>\frac{\partial U\left(x,t\right)}{\partial t} = a^2\frac{\partial^2 U\left(x,t\right)}{\partial x^2}</math>
X=new double[i_shagov+3];
 
for(int i=0;i<i_shagov+3;i++)
 
{
 
X[i]=x_min+(i-1)*shagx + my_id*i_shagov*shagx + my_id*shagx;
 
}
 
T=new double[i_shagov+3];
 
Tn=new double[i_shagov+3];
 
for(int i=0;i<i_shagov+3;i++) // Initial condition t=0
 
{
 
T[i]=initial_condition(X[i],0);
 
}
 
/*
 
myFile.open(file_name,ios::app);
 
  
for(int k=1;k<i_shagov+2;k++)
+
Введем равномерную сетку <math>0 < x_i < L</math> с шагом разбиения <math>Δx</math>. Шаг по времени назовем <math>Δt</math>
{
+
Построим явную конечно-разностную схему:
myFile<<T[k]<<"\t";
+
:<math>\frac{U_i^{n+1}-U_i^{n}}{Δ t} = \frac{a^2}{Δx^2}\left(U_{i+1}^{n} - 2U_{i}^{n}+U_{i-1}^{n}\right)</math>
}
+
Где, <math>U_i</math> — значение температуры в <math>i</math>-ом узле.
myFile<< "\n";
+
* Условие сходимости явной схемы:<math>dt<dx^2/2</math>, где dt - шаг по времени, dx - шаг по координате
myFile.close();
 
*/
 
for(int j=1;j<ShagovPoT;j++)
 
{
 
  
if(my_id==0)
+
===Применение технологии MPI===
// The first process will only send and recive data with its right process
+
Разветвление для уравнения теплопроводности осуществляется путем разбиением отрезка интегрирования на некоторые интервалы. На каждом интервале, процесс интегрирования осуществляется отдельным процессом, при этом в связи с использованием явной схемы, соседние процессы должны обменивать крайними значениями, получены на предыдущем шаге, для выполнения следующего шага.
{
+
[[File:Sendandreceive.png|Схема передачи данных между процессами|center]]
double right_send=T[i_shagov+1];
+
: Первый процесс обменивается данными только с вторым процессом
double right_recive;
+
: Последний процесс обменивается данными только с предпоследним процессом
MPI_Send(&right_send,1,MPI_DOUBLE,1,0,MPI_COMM_WORLD);
+
: Все центральные процессы обмениваются с процессами слево, и справо
MPI_Recv(&right_recive,1,MPI_DOUBLE,1,0,MPI_COMM_WORLD,MPI_STATUSES_IGNORE);
+
* Начальные и краиние значения на каждом шаге вычисляются по начальным и граничным условиям.
T[i_shagov+2]=right_recive;
 
}
 
else if(my_id==p-1)
 
// The last process will only send and recive data with its left process
 
{
 
double  left_send=T[1];
 
MPI_Send(&left_send,1,MPI_DOUBLE,my_id-1,0,MPI_COMM_WORLD);
 
double left_recive;
 
MPI_Recv(&left_recive,1,MPI_DOUBLE,my_id-1,0,MPI_COMM_WORLD,MPI_STATUSES_IGNORE);
 
T[0]=left_recive;
 
}
 
else
 
{
 
//midle process send and recive message with left and right processes
 
double  left_send=T[1];
 
MPI_Send(&left_send,1,MPI_DOUBLE,my_id-1,0,MPI_COMM_WORLD);
 
double  left_recive;
 
MPI_Recv(&left_recive,1,MPI_DOUBLE,my_id-1,0,MPI_COMM_WORLD,MPI_STATUSES_IGNORE);
 
T[0]=left_recive;
 
  
double  right_send= T[i_shagov+1];
+
===Данные для расчета===
double right_recive;
+
:<math> \begin{cases}
MPI_Send(&right_send,1,MPI_DOUBLE,my_id+1,0,MPI_COMM_WORLD);
+
  a=0;b=1\\
MPI_Recv(&right_recive,1,MPI_DOUBLE,my_id+1,0,MPI_COMM_WORLD,MPI_STATUSES_IGNORE);
+
  M1(t)=6t+0.887\\
T[i_shagov+2]=right_recive;
+
  M2(t)=0.0907\\
}
+
  U0(x)=cos(x+0.48)\\
for(int i=1;i<i_shagov+2;i++)
+
  f(x,t)=0\\
{
+
  k=1
//Tn[i]=T[i]+ shagt/shagx/shagx*(T[i+1]+T[i-1]-2*T[i]);
+
\end{cases}</math>
Tn[i]=5;
 
}
 
if(my_id==0) //поправить самый левый и самый правый интервала по гранич. услов.
 
{
 
Tn[1]=boundary_condition(j*shagt,1);
 
}
 
else if(my_id==p-1)
 
{
 
Tn[i_shagov+1]=boundary_condition(j*shagt,2);
 
}
 
/*
 
// print result to files
 
myFile.open(file_name,ios::app);
 
  
for(int k=1;k<i_shagov+2;k++)
+
==Результаты==
{
+
* Решение
myFile<<Tn[k]<<"\t";
+
** 2 процесса
}
+
[[File:Result.PNG|thumb|500px|Решение при запуске 2-х процессов|center]]
myFile<< "\n";
+
*4 процесса
myFile.close();
+
[[File:Result2.png|thumb|500px|Решение при запуске 4-х процессов|center]]
*/
+
* Погрешность вычисления
for(int i=0;i<i_shagov+3;i++)
+
* Зависимость времени расчета от количества процессов при постоянных шагах вычисления: dx = 0.001; dt = 0.000001
{
 
T[i]=Tn[i];
 
}
 
T[0]=T[1];
 
T[i_shagov+2]=T[i_shagov+1];
 
}
 
 
MPI_Finalize();
 
if(my_id==0) 
 
{
 
  finish=clock();// Stop recording time
 
  double second =finish-start;
 
  //myFile.open(file_name,ios::app);
 
  infoFile.open("infoSolution.txt");
 
  infoFile<<"Calculating with "<<p<<" processes"<<endl;
 
  infoFile<<"It took "<< second/CLOCKS_PER_SEC<< " seconds";
 
  //infoFile<<""
 
  //printf ("It took me %d clicks (%f seconds).\n",second,((float)second)/CLOCKS_PER_SEC);
 
}
 
}
 
double initial_condition ( double x, double time )
 
{
 
double value;
 
value=cos(x+0.48);
 
return value;
 
}
 
double boundary_condition ( double t,int flag)
 
{
 
double value;
 
if(flag==1)
 
{
 
value=6*t+0.886994923;
 
}
 
else if(flag==2)
 
{
 
value=0.090671624;
 
}
 
return value;
 
  
}
+
[[File:Processing time.PNG|thumb|500px|Зависимость времени расчета от кол. процессов|center]]
 
+
{| class="wikitable" width="300" floating="center"
==Цель работы==
+
!Количество процессов
 +
!Время рассчета (сек)
 +
|-
 +
|2
 +
|96.58
 +
|-
 +
|4
 +
|49.4
 +
|-
 +
|8
 +
|28.66
 +
|-
 +
|10
 +
|23.63
 +
|-
 +
|20
 +
|12.89
 +
|-
 +
|30
 +
|9.27
 +
|-
 +
|40
 +
| 7.52
 +
|}
 +
Для малого числа узлов в сетке использовать многопроцессорные вычисления не выгодно: время работы программы неуменьшается.
 +
Заметим что при увеличении количества процессов, скорость расчета параллельно повысилась
 +
==Полезные ссылки==
 +
[https://ru.wikipedia.org/wiki/%D0%A3%D1%80%D0%B0%D0%B2%D0%BD%D0%B5%D0%BD%D0%B8%D0%B5_%D1%82%D0%B5%D0%BF%D0%BB%D0%BE%D0%BF%D1%80%D0%BE%D0%B2%D0%BE%D0%B4%D0%BD%D0%BE%D1%81%D1%82%D0%B8 Уравнение теплопроводности]

Текущая версия на 22:38, 14 января 2016

Постановка задачи[править]

Пример численного решения уравнения теплопроводности. Цветом и высотой поверхности передана температура данной точки.

Решается однородное уравнение теплопроводности на промежутке [math]\left[a\ldots b\right][/math]

[math]\frac{\partial U\left(x,t\right)}{\partial t} - k^2\frac{\partial^2 U\left(x,t\right)}{\partial x^2} = f(x,t)[/math]

С граничными условиями

[math] \begin{cases} U(a,t) = M1(t) \\ U(b,t) = M2(t) \end{cases}[/math]

и начальным распределением температуры

[math]U(x,0) = U0(x)[/math]
  • Где :[math]f(x,t), U0(x), M1(t), M2(t)[/math] - Известные функции

Реализация[править]

Конечно-разностная схема[править]

Явная разностная схема

Задача содержит производную по времени первого порядка и производную по пространственной координате второго порядка. Запишем исходное уравнение в виде

[math]\frac{\partial U\left(x,t\right)}{\partial t} = a^2\frac{\partial^2 U\left(x,t\right)}{\partial x^2}[/math]

Введем равномерную сетку [math]0 \lt x_i \lt L[/math] с шагом разбиения [math]Δx[/math]. Шаг по времени назовем [math]Δt[/math] Построим явную конечно-разностную схему:

[math]\frac{U_i^{n+1}-U_i^{n}}{Δ t} = \frac{a^2}{Δx^2}\left(U_{i+1}^{n} - 2U_{i}^{n}+U_{i-1}^{n}\right)[/math]

Где, [math]U_i[/math] — значение температуры в [math]i[/math]-ом узле.

  • Условие сходимости явной схемы:[math]dt\lt dx^2/2[/math], где dt - шаг по времени, dx - шаг по координате

Применение технологии MPI[править]

Разветвление для уравнения теплопроводности осуществляется путем разбиением отрезка интегрирования на некоторые интервалы. На каждом интервале, процесс интегрирования осуществляется отдельным процессом, при этом в связи с использованием явной схемы, соседние процессы должны обменивать крайними значениями, получены на предыдущем шаге, для выполнения следующего шага.

Схема передачи данных между процессами
Первый процесс обменивается данными только с вторым процессом
Последний процесс обменивается данными только с предпоследним процессом
Все центральные процессы обмениваются с процессами слево, и справо
  • Начальные и краиние значения на каждом шаге вычисляются по начальным и граничным условиям.

Данные для расчета[править]

[math] \begin{cases} a=0;b=1\\ M1(t)=6t+0.887\\ M2(t)=0.0907\\ U0(x)=cos(x+0.48)\\ f(x,t)=0\\ k=1 \end{cases}[/math]

Результаты[править]

  • Решение
    • 2 процесса
Решение при запуске 2-х процессов
  • 4 процесса
Решение при запуске 4-х процессов
  • Погрешность вычисления
  • Зависимость времени расчета от количества процессов при постоянных шагах вычисления: dx = 0.001; dt = 0.000001
Зависимость времени расчета от кол. процессов
Количество процессов Время рассчета (сек)
2 96.58
4 49.4
8 28.66
10 23.63
20 12.89
30 9.27
40 7.52

Для малого числа узлов в сетке использовать многопроцессорные вычисления не выгодно: время работы программы неуменьшается. Заметим что при увеличении количества процессов, скорость расчета параллельно повысилась

Полезные ссылки[править]

Уравнение теплопроводности