00001
00002
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
00014
00015
00016
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
00026
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
00050
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
00068
00069 #define M 200
00070 #define N 200
00071
00072 #define STANDING_WAVE 1
00073 #define OVERDENSE 1
00074
00075
00076
00077 #define EPS 0.5
00078 #define TMAX 5.0
00079
00080
00081
00082 #define A 1.0
00083 #define GAMMA 1.666667
00084
00085
00086
00087 real xmin, xmax, dx, ymin, ymax, dy;
00088 real rhoi = 1.0, amp = 0.1;
00089
00090
00091
00092
00093
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
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
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
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
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
00169
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
00185
00186 int i, j;
00187
00188
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
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
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
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 }