/* ------------------------------------------------------------------------ * SERIAL Concurrent Wave Equation - C Version * FILE: ser_wave.c * DESCRIPTION: * This program implements the concurrent wave equation described * in Chapter 5 of Fox et al., 1988, Solving Problems on Concurrent * Processors, vol 1. * * A vibrating string is decomposed into points. In the parallel * version each processor is responsible for updating the amplitude * of a number of points over time. * * At each iteration, each processor exchanges boundary points with * nearest neighbors. This version uses low level sends and receives * to exchange boundary points. * * LAST REVISED: 11/25/95 Blaise Barney * ------------------------------------------------------------------------*/ #include #include #include #include #define MAXPOINTS 1000 #define MAXSTEPS 10000 #define MINPOINTS 20 #define PI 3.14159265 void init_param(void); void init_line(void); void update (void); int nsteps, /* number of time steps */ tpoints, /* total points along string */ rcode; /* generic return code */ double values[MAXPOINTS+2], /* values at time t */ oldval[MAXPOINTS+2], /* values at time (t-dt) */ newval[MAXPOINTS+2]; /* values at time (t+dt) */ /* ------------------------------------------------------------------------ * Obtains input values from user * ------------------------------------------------------------------------ */ void init_param(void) { char tchar[8]; /* set number of points, number of iterations */ tpoints = 0; nsteps = 0; while ((tpoints < MINPOINTS) || (tpoints > MAXPOINTS)) { printf("Enter number of points along vibrating string\n"); scanf("%s", tchar); tpoints = atoi(tchar); if ((tpoints < MINPOINTS) || (tpoints > MAXPOINTS)) printf("enter value between %d and %d\n", MINPOINTS, MAXPOINTS); } while ((nsteps < 1) || (nsteps > MAXSTEPS)) { printf("Enter number of time steps\n"); scanf("%s", tchar); nsteps = atoi(tchar); if ((nsteps < 1) || (nsteps > MAXSTEPS)) printf("enter value between 1 and %d\n", MAXSTEPS); } printf("points = %d, steps = %d\n", tpoints, nsteps); } /* ------------------------------------------------------------------------ * All processes initialize points on line * --------------------------------------------------------------------- */ void init_line(void) { int i, j, k; double x, fac; /* calculate initial values based on sine curve */ fac = 2.0 * PI; k = 0; for (j = 1; j <= tpoints; j++, k++) { x = (double)k/(double)(tpoints - 1); values[j] = sin (fac * x); } for (i = 1; i <= tpoints; i++) oldval[i] = values[i]; } /* ------------------------------------------------------------------------- * Calculate new values using wave equation * -------------------------------------------------------------------------*/ void do_math(int i) { double dtime, c, dx, tau, sqtau; dtime = 0.3; c = 1.0; dx = 1.0; tau = (c * dtime / dx); sqtau = tau * tau; newval[i] = (2.0 * values[i]) - oldval[i] + (sqtau * (values[i-1] - (2.0 * values[i]) + values[i+1])); } /* ------------------------------------------------------------------------- * Update the points a specified number of times * -------------------------------------------------------------------------*/ void update() { int i, j, tpts; /* update values for each point along string */ /* update points along line */ for (j = 1; j <= tpoints; j++) { /* global endpoints */ if ((j == 1) || (j == tpoints)) newval[j] = 0.0; else do_math(j); } for (j = 1; j <= tpoints; j++) { oldval[j] = values[j]; values[j] = newval[j]; } /* print it out for validation */ tpts = (tpoints < 10) ? tpoints: 10; printf("first %d points (for validation):\n", tpts); for (i = 0; i < tpts; i++) printf("%4.2f ", values[i]); printf("\n"); } /* ------------------------------------------------------------------------ * Main program * ------------------------------------------------------------------------ */ main() { int left, right; /* get program parameters and initialize wave values */ init_param(); init_line(); /* update values along the line for nstep time steps */ update(); return 0; }