/************************************************* * Laplace Serial C Version * * A_new is initially 0.0 * Boundaries are as follows: * * 0 T 0 * 0 +-------------------+ 0 * | | * | | * | | * T | | T * | | * | | * | | * 0 +-------------------+ 100 * 0 T 100 * * ************************************************/ #include #include #include #include // size of plate #define COLUMNS 1000 #define ROWS 1000 // largest permitted change in temp (This value takes about 3400 steps) #define tolerance 0.01 double A_new[ROWS+2][COLUMNS+2]; // temperature grid double A[ROWS+2][COLUMNS+2]; // temperature grid from last iteration // helper routines void initialize(); void track_progress(int iter); int main(int argc, char *argv[]) { int i, j; // grid indexes int max_iterations; // number of iterations int iteration=1; // current iteration double dA=100; // largest change in t struct timeval start_time, stop_time, elapsed_time; // timers printf("Maximum iterations [100-4000]?\n"); scanf("%d", &max_iterations); gettimeofday(&start_time,NULL); // Unix timer initialize(); // initialize Temp_last including boundary conditions // do until error is minimal or until max steps while ( dA > tolerance && iteration <= max_iterations ) { // main calculation: average my four neighbors for(i = 1; i <= ROWS; i++) { for(j = 1; j <= COLUMNS; j++) { A_new[i][j] = 0.25 * (A[i+1][j] + A[i-1][j] + A[i][j+1] + A[i][j-1]); } } dA = 0.0; // reset largest temperature change // copy grid to old grid for next iteration and find latest dA for(i = 1; i <= ROWS; i++){ for(j = 1; j <= COLUMNS; j++){ dA = fmax( fabs(A_new[i][j]-A[i][j]), dA); A[i][j] = A_new[i][j]; } } // periodically print test values if((iteration % 100) == 0) { track_progress(iteration); } iteration++; } gettimeofday(&stop_time,NULL); timersub(&stop_time, &start_time, &elapsed_time); // Unix time subtract routine printf("\nMax error at iteration %d was %f\n", iteration-1, dA); printf("Total time was %f seconds.\n", elapsed_time.tv_sec+elapsed_time.tv_usec/1000000.0); } // initialize plate and boundary conditions // Temp_last is used to to start first iteration void initialize(){ int i,j; for(i = 0; i <= ROWS+1; i++){ for (j = 0; j <= COLUMNS+1; j++){ A[i][j] = 0.0; } } // these boundary conditions never change throughout run // set left side to 0 and right to a linear increase for(i = 0; i <= ROWS+1; i++) { A[i][0] = 0.0; A[i][COLUMNS+1] = (100.0/ROWS)*i; } // set top to 0 and bottom to linear increase for(j = 0; j <= COLUMNS+1; j++) { A[0][j] = 0.0; A[ROWS+1][j] = (100.0/COLUMNS)*j; } } // print diagonal in bottom right corner where most action is void track_progress(int iteration) { int i; printf("---------- Iteration number: %d ------------\n", iteration); for(i = ROWS-5; i <= ROWS; i++) { printf("[%d,%d]: %5.2f ", i, i, A_new[i][i]); } printf("\n"); }