/* This c code is a finite-difference solver for the one way wave equation p_t + c p_x = 0 ; p(x,0) = A exp(-(x-x0)^2) -E < x < E */ #include #include #include /* This is the Master proc. It reads all the input from stdin and outs the files to times and filexxxx based on the input given. */ void RunMaster(int size) { float c,A,E,dx,dt; int numTimes,numGrids; char fileName[256]="file",buf[256]=""; float *p1,*p2,*temp; FILE *fout; int i,j,k,length,pos,*lengths; int result; MPI_Status status,*statuses; MPI_Request request,*requests; int count; //read in the input values printf("Give c : "); scanf("%f",&c); printf("Give A : "); scanf("%f",&A); printf("Give E : "); scanf("%f",&E); printf("Give the grid size dx : "); scanf("%f",&dx); printf("Give the time step dt : "); scanf("%f",&dt); printf("Give the number of time steps : "); scanf("%d",&numTimes); printf("Save matlab data as : ");fflush(stdout); //we must flush or we will read the newline just outputed scanf("%s",fileName); numGrids=2*E/dx; //calc num of grids // printf("The number of grids is %d \n ",numGrids); // Build the time file fout=fopen("times","w"); //output the times file if (fout==NULL) { perror("times"); return; } for(i=0;i<=numTimes;i++) { fprintf(fout,"%f\n",i*dt); //output the times into the file } fclose(fout); // Set up the memory for the pressure p1=(float *)malloc(sizeof(float)*(numGrids+2)); //create p1,p2 if (p1==NULL) { perror("memory"); return; } p2=(float *)malloc(sizeof(float)*(numGrids+2)); if (p2==NULL) { perror("memory"); free((void *)p1); return; } // Broadcast the global values to the nodes result=MPI_Bcast((void *)&c,1,MPI_FLOAT,0,MPI_COMM_WORLD); if (result!=MPI_SUCCESS) return; result=MPI_Bcast((void *)&A,1,MPI_FLOAT,0,MPI_COMM_WORLD); if (result!=MPI_SUCCESS) return; result=MPI_Bcast((void *)&E,1,MPI_FLOAT,0,MPI_COMM_WORLD); if (result!=MPI_SUCCESS) return; result=MPI_Bcast((void *)&dx,1,MPI_FLOAT,0,MPI_COMM_WORLD); if (result!=MPI_SUCCESS) return; result=MPI_Bcast((void *)&dt,1,MPI_FLOAT,0,MPI_COMM_WORLD); if (result!=MPI_SUCCESS) return; result=MPI_Bcast((void *)&numTimes,1,MPI_INT,0,MPI_COMM_WORLD); if (result!=MPI_SUCCESS) return; result=MPI_Bcast((void *)&numGrids,1,MPI_INT,0,MPI_COMM_WORLD); if (result!=MPI_SUCCESS) return; snprintf(buf,255,"%s%08d",fileName,0); //create filename for the initial output file fout=fopen(buf,"w"); if (fout==NULL) { perror(buf); free((void *)p1); free((void *)p2); return; } // The initial conditions i=0; //set up i pos=0; //calc the initial values for p1 array requests=(MPI_Request *)malloc(sizeof(MPI_Request)*3*(size-1)); statuses=(MPI_Status *)malloc(sizeof(MPI_Status)*3*(size-1)); lengths=(int *)malloc(sizeof(int)*(size-1)); j=1; // Send grids to each processor (node). for(k=1;k1)){ lengths[k-1]=(numGrids+2)%(size-1); printf("The number of grids is %d \n ",lengths[k-1]); } */ result=MPI_Isend((void *)&(lengths[k-1]),1,MPI_INT,k,201, MPI_COMM_WORLD,&(requests[(k-1)*3+2])); if (result!=MPI_SUCCESS) return; i+=lengths[k-1]; } //MPI_Waitall((size-1)*3,requests,statuses); // Send p to each processor (node). for(k=1;k1)){ length=(numGrids+2)%(size-1); } */ result=MPI_Recv((void *)&(p1[pos]),length,MPI_FLOAT,k,202, MPI_COMM_WORLD,&status); if (result!=MPI_SUCCESS) return; result=MPI_Get_count(&status,MPI_FLOAT,&count); if (result!=MPI_SUCCESS) return; if (count!=length) return; pos+=length; } fwrite(p1,sizeof(float),numGrids+2,fout); // for(i=0;i<(numGrids+2);i++) fprintf(fout,"%f\n",p1[i]); fclose(fout); // Go through the time steps. Send and receive data from the processors (nodes). for(i=1;i<=numTimes;i++) { //run for the num of time steps sprintf(buf,"%s%08d",fileName,i); //create filename fout=fopen(buf,"w"); if (fout==NULL) { perror(buf); free((void *)p1); free((void *)p2); return; } // send p pos=0; for(j=1;j