Main Page   Class Hierarchy   Data Structures   File List   Data Fields   Globals  

hydro2.c

Go to the documentation of this file.
00001 
00002 /* Version of hydro2 with ximage calls built in... */
00003 
00004 #include <stdio.h>
00005 #include <math.h>
00006 #include <stdlib.h>
00007 
00008 typedef double real;
00009 #define local static
00010 
00011 /*------------------------------------------------------------------------*/
00012 
00013 /* Interface routine between the hydro and the X display.
00014  * The job of this function is to take the rho data and scale
00015  * appropriately into a character array, then send the array
00016  * the X-display routines.
00017  */
00018 
00019 static unsigned char *data = NULL;
00020 static nrep = 0;
00021 static unsigned char red[256], green[256], blue[256];
00022 
00023 local void output_grid(int m, int n, real *rho, real rhoi, real amp)
00024 {
00025   /* Scale and write the rho grid to the X display.
00026      Note that rho is really a 2-D array of dimensions (m+2) x (n+2). */
00027 
00028   unsigned char c;
00029   int i, j, k = 0;
00030 
00031   if (!data) {
00032     nrep = get_nrep();
00033     get_cmap(red, green, blue);
00034     data = (unsigned char*)malloc(nrep*m*n);
00035   }
00036 
00037   for (j = 1; j <= n; j++)
00038     for (i = 1; i <= m; i++) {
00039 
00040       c = 128 * (1 + (*(rho + i + j*(m+2)) - rhoi) / amp);
00041       if (c > 255) c = 255;
00042 
00043       if (nrep == 1) {
00044 
00045         *(data + k++) = c;
00046 
00047       } else {
00048 
00049         /* Remap the data:  Turn c into a 3-byte (B, G, R) sequence
00050            followed by a null byte. */
00051 
00052         *(data + k++) = blue[c];
00053         *(data + k++) = green[c];
00054         *(data + k++) = red[c];
00055         *(data + k++) = 0;
00056 
00057       }
00058 
00059     }
00060 
00061   ximage(data);
00062 
00063 }
00064 
00065 /*------------------------------------------------------------------------*/
00066 
00067 /* Grid parameters */
00068 
00069 #define M       200
00070 #define N       200
00071 
00072 #define STANDING_WAVE   1
00073 #define OVERDENSE       1
00074 
00075 /* Timestep parameters (smaller courant parameter in 2D) */
00076 
00077 #define EPS     0.5
00078 #define TMAX    5.0
00079 
00080 /* Equation of state */
00081 
00082 #define A       1.0
00083 #define GAMMA   1.666667
00084 
00085 /* May be most convenient to work with static data in this case... */
00086 
00087 real xmin, xmax, dx, ymin, ymax, dy;
00088 real rhoi = 1.0, amp = 0.1;
00089 
00090 /* NOTE: Indices run from 0 to M(N)+1, with 0 and M+1 used to implement
00091  *       the B.C.s.  The first "physical" zone is #1, which (in x) runs from
00092  *       xmin to xmin+dx (and similarly for y).  Density and presssure are
00093  *       defined at the centers of zones: rho[1] is at x+dx/2, and so on.
00094  */
00095 
00096 real u[M+2][N+2], v[M+2][N+2], rho[M+2][N+2], p[M+2][N+2];
00097 real u0[M+2][N+2], v0[M+2][N+2], rho0[M+2][N+2];
00098 
00099 real csound, dtcourant;
00100 real dt, dtdx, dtdy;
00101 
00102 inline local real pressure(real rho)
00103 {
00104   return A*pow(rho, GAMMA);
00105 }
00106 
00107 local void initialize_grid()
00108 {
00109   /* Initial conditions. */
00110 
00111   int i, j;
00112   real nosc = 2;
00113   real delx, dely;
00114 
00115   xmin = 0.0;
00116   xmax = 1.0;
00117   delx = xmax - xmin;
00118   dx = delx / M;
00119 
00120   ymin = 0.0;
00121   ymax = 1.0;
00122   dely = ymax - ymin;
00123   dy = dely / M;
00124 
00125   for (i = 1; i <= M; i++) {
00126     real x = xmin + (i-0.5)*dx;
00127     for (j = 1; j <= N; j++) {
00128       real y = ymin + (j-0.5)*dy;
00129 
00130 #if STANDING_WAVE
00131 
00132       /* Standing wave. */
00133 
00134       u[i][j] = 0.0;
00135       v[i][j] = 0.0;
00136       rho[i][j] = rhoi * (1.0 + amp * sin(2*M_PI*nosc*x/delx)
00137                                     * sin(2*M_PI*nosc*y/dely));
00138 
00139 #else if OVERDENSE
00140 
00141       /* Overdense region. */
00142 
00143       u[i][j] = 0.0;
00144       v[i][j] = 0.0;
00145       if ((x-0.5)*(x-0.5) + (y-0.5)*(y-0.5) < 0.01)
00146         rho[i][j] = rhoi * (1.0 + amp);
00147       else
00148         rho[i][j] = rhoi;
00149 
00150 #endif
00151 
00152     }
00153   }
00154 
00155   csound = sqrt(GAMMA*pressure(rhoi)/rhoi);
00156   dtcourant = dx/csound;
00157 
00158   /* Work at a fraction EPS of the Courant limit. */
00159 
00160   dt = EPS*dtcourant;
00161   dtdx = 0.5*dt/dx;
00162   dtdy = 0.5*dt/dy;
00163 
00164 }
00165 
00166 local void copy_grid()
00167 {
00168   /* Make copies of u, v and rho for differencing below, and
00169    * set up the pressure using the equation of state. */
00170 
00171   int i, j;
00172 
00173   for (i = 1; i <= M; i++)
00174     for (j = 1; j <= N; j++) {
00175       u0[i][j] = u[i][j];
00176       v0[i][j] = v[i][j];
00177       rho0[i][j] = rho[i][j];
00178       p[i][j] = pressure(rho[i][j]);
00179     }
00180 }
00181 
00182 local void apply_bc()
00183 {
00184   /* Apply boundary conditions (periodic, here). */
00185 
00186   int i, j;
00187 
00188   /* Top and bottom. */
00189 
00190   for (i = 1; i <= M; i++) {
00191     u0[i][0] = u[i][N];
00192     v0[i][0] = v[i][N];
00193     rho0[i][0] = rho[i][N];
00194     p[i][0] = p[i][N];
00195 
00196     u0[i][N+1] = u[i][1];
00197     v0[i][N+1] = v[i][1];
00198     rho0[i][N+1] = rho[i][1];
00199     p[i][N+1] = p[i][1];
00200   }
00201 
00202   /* Left and right edges. */
00203 
00204   for (j = 0; j <= N; j++) {
00205     u0[0][j] = u[M][j];
00206     v0[0][j] = v[M][j];
00207     rho0[0][j] = rho[M][j];
00208     p[0][j] = p[M][j];
00209 
00210     u0[M+1][j] = u[1][j];
00211     v0[M+1][j] = v[1][j];
00212     rho0[M+1][j] = rho[1][j];
00213     p[M+1][j] = p[1][j];
00214   }
00215 
00216 }
00217 
00218 local void single_step()
00219 {
00220   /* Lax differencing scheme. */
00221 
00222   int i, j;
00223 
00224   for (i = 1; i <= M; i++)
00225     for (j = 1; j <= N; j++) {
00226 
00227       real dux = u0[i+1][j] - u0[i-1][j];
00228       real duy = u0[i][j+1] - u0[i][j-1];
00229       real dvx = v0[i+1][j] - v0[i-1][j];
00230       real dvy = v0[i][j+1] - v0[i][j-1];
00231       real dpx = p[i+1][j] - p[i-1][j];
00232       real dpy = p[i][j+1] - p[i][j-1];
00233 
00234       real drux = rho0[i+1][j]*u0[i+1][j] - rho0[i-1][j]*u0[i-1][j];
00235       real drvy = rho0[i][j+1]*v0[i][j+1] - rho0[i][j-1]*v0[i][j-1];
00236 
00237       u[i][j] = 0.25*(u0[i][j+1] + u0[i][j-1] + u0[i+1][j] + u0[i-1][j])
00238                 - dtdx*(dpx/rho0[i][j] + u0[i][j]*dux)
00239                 - dtdy*v0[i][j]*duy;
00240 
00241       v[i][j] = 0.25*(v0[i][j+1] + v0[i][j-1] + v0[i+1][j] + v0[i-1][j])
00242                 - dtdx*u0[i][j]*dvx
00243                 - dtdy*(dpy/rho0[i][j] + v0[i][j]*dvy);
00244 
00245       rho[i][j] = 0.25*(rho0[i][j+1] + rho0[i][j-1]
00246                          + rho0[i+1][j] + rho0[i-1][j])
00247                   - dtdx*drux - dtdy*drvy;
00248     }
00249 }
00250 
00251 
00252 local void step()
00253 {
00254   /* Take a time step. */
00255 
00256   copy_grid();
00257   apply_bc();
00258   single_step();
00259 }
00260 
00261 void main(int argc, char *argv[])
00262 {
00263   int i, nsteps = 200, nout = 2;
00264 
00265   initialize_grid();
00266   ximage_init(M, N);
00267   output_grid(M, N, (real*)rho, rhoi, amp);
00268 
00269   for (i = 0; i < nsteps; i++) {
00270     step();
00271     fprintf(stderr, "end of step %d\n", i);
00272     if ((i+1)%nout == 0) output_grid(M, N, (real*)rho, rhoi, amp);
00273   }
00274 
00275   ximage_quit();
00276 
00277 }

Generated at Sun Feb 24 09:57:04 2002 for STARLAB by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001