|
|
Строка 10: |
Строка 10: |
| 0<x<1;0<t<1 | | 0<x<1;0<t<1 |
| ==Релизация MPI== | | ==Релизация MPI== |
− | # include <cstdlib>
| |
− | # 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;
| |
− | char file_name[100];
| |
− | sprintf(file_name, "result%i.txt", my_id); //file_name
| |
− |
| |
− | 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++)
| |
− | {
| |
− | myFile<<T[k]<<"\t";
| |
− | }
| |
− | myFile<< "\n";
| |
− | myFile.close();
| |
− | */
| |
− | for(int j=1;j<ShagovPoT;j++)
| |
− | {
| |
− |
| |
− | if(my_id==0)
| |
− | // The first process will only send and recive data with its right process
| |
− | {
| |
− | 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;
| |
− | MPI_Send(&right_send,1,MPI_DOUBLE,my_id+1,0,MPI_COMM_WORLD);
| |
− | MPI_Recv(&right_recive,1,MPI_DOUBLE,my_id+1,0,MPI_COMM_WORLD,MPI_STATUSES_IGNORE);
| |
− | T[i_shagov+2]=right_recive;
| |
− | }
| |
− | for(int i=1;i<i_shagov+2;i++)
| |
− | {
| |
− | //Tn[i]=T[i]+ shagt/shagx/shagx*(T[i+1]+T[i-1]-2*T[i]);
| |
− | 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";
| |
− | }
| |
− | myFile<< "\n";
| |
− | myFile.close();
| |
− | */
| |
− | for(int i=0;i<i_shagov+3;i++)
| |
− | {
| |
− | 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;
| |
− |
| |
− | }
| |
| | | |
| ==Цель работы== | | ==Цель работы== |
Решение краевой задачи для одномерного уравнения теплопроводности
dU/dt-d2U/dx2=f(x,t), a<x<b, 0<t<Tk
Начальное условие U(x,0)=U0(x)
Конечные условия U(a,t)=M1(t); U(b,t)=M2(t);
Где f(x,t), U0(x), M1(t), M2(t) - Заданные функции