00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 #include "utilf.h"
00055 #include "markers.h"
00056 #include "extra.h"
00057 #include "momentum.h"
00058 #ifdef MG
00059 #include "mg.h"
00060 #else
00061 #include "vmg.h"
00062 #endif
00063 #include "make_bc.h"
00064
00065 static void coli(real2D cc,
00066 real2D nu1, real2D nu2, real2D nu3, real2D nu4,
00067 real2D c0, real2D c1, real2D c2, real2D c3, real2D c4,
00068 int nx, int ny);
00069
00070 void momentum(real2D u, real2D v,
00071 real2D a, real2D c,
00072 real2D w1,
00073 real2D S11, real2D S22, real2D S12,
00074 real2D w2,
00075 real visliq,
00076 real gx, real gy,
00077 real tau,
00078 int nx, int ny)
00079 {
00080 int i, j;
00081 real h;
00082 real gx2, gy2, tau2h;
00083
00084 h = 1. / (nx - 2);
00085 tau2h = sq(tau) / h;
00086 gx2 = gx * tau2h;
00087 gy2 = gy * tau2h;
00088 visliq *= tau/(h*h);
00089
00090
00091
00092
00093 for (i = 2; i <= nx - 1; i++)
00094 {
00095 for (j = 2; j <= ny - 1; j++)
00096 if (IN(a[i-1][j]))
00097 w1[i][j] = 0.25*(
00098 (u[i][j] + u[i][j-1])*(v[i][j] + v[i-1][j])
00099 - (u[i][j+1] + u[i][j])*(v[i][j+1] + v[i-1][j+1])
00100 + sq(u[i-1][j] + u[i][j]) - sq(u[i][j] + u[i+1][j])
00101
00102 - (v[i][j] + v[i][j+1] + v[i-1][j+1] + v[i-1][j])
00103 *u[i][j]/((real)j - 1.5));
00104
00105 for (j = 3; j <= ny - 1; j++)
00106 if (IN(c[i][j-1]))
00107 w2[i][j] = 0.25*(
00108 (u[i][j] + u[i][j-1])*(v[i][j] + v[i-1][j])
00109 - (u[i+1][j] + u[i+1][j-1])*(v[i+1][j] + v[i][j])
00110 + sq(v[i][j-1] + v[i][j]) - sq(v[i][j] + v[i][j+1])
00111
00112 - sq(2.0*v[i][j])/((real)j - 2.0));
00113 }
00114
00115
00116
00117
00118
00119 for (i = 2; i <= nx - 1; i++)
00120 {
00121 for (j = 2; j <= ny - 1; j++)
00122 if (IN(a[i-1][j]))
00123 u[i][j] += w1[i][j]
00124 + S12[i][j+1] - S12[i][j] + S11[i][j] - S11[i-1][j]
00125
00126
00127
00128
00129 + gx2;
00130 for (j = 3; j <= ny - 1; j++)
00131 if (IN(c[i][j-1]))
00132 v[i][j] += w2[i][j]
00133 + S12[i+1][j] - S12[i][j] + S22[i][j] - S22[i][j-1]
00134
00135 + (0.5*(S22[i][j] + S22[i][j-1]) - 2.*visliq*v[i][j]/
00136 ((real)j - 2.0))
00137 /((real)j - 2.0)
00138 + gy2;
00139 }
00140 }
00141
00142
00143 void pressure(real2D u, real2D v, real2D p,
00144 real2D cc, real2D a, real2D c,
00145 real2D div,
00146 real2D nu1, real2D nu2, real2D nu3, real2D nu4,
00147 real2D c0, real2D c1, real2D c2, real2D c3, real2D c4,
00148 #ifdef MG
00149 int ncycle, int npre, int npost, real pa,
00150 #else
00151 real epsilon,
00152 #endif
00153 int nx, int ny, int ng)
00154 {
00155 int i, j;
00156 real h = 1.0/(nx - 2), hi2;
00157 real p0, p3, p4, n3, n4;
00158 hi2 = 1./(h*h);
00159
00160
00161
00162
00163
00164
00165 for (i = 2; i <= nx - 1; i++)
00166 for (j = 2; j <= ny - 1; j++)
00167 if (IN(cc[i][j]))
00168 div[i][j] = (((real)j - 1.)*v[i][j+1] - ((real)j - 2.)*v[i][j] +
00169 ((real)j - 1.5)*(u[i+1][j] - u[i][j]))
00170 #ifndef MG
00171 *hi2
00172 #endif
00173 ;
00174 else
00175 div[i][j] = 0.0;
00176
00177 datbarray(div, nx, ny, "divbefore");
00178 datbarray(p, nx, ny, "pbefore");
00179 datbarray(cc, nx, ny, "cc");
00180 datbarray(u, nx, ny, "ubefore");
00181 datbarray(v, nx, ny, "vbefore");
00182
00183 coli(cc,
00184 nu1, nu2, nu3, nu4,
00185 c0, c1, c2, c3, c4,
00186 nx, ny);
00187 #ifdef MG
00188
00189
00190
00191
00192
00193 for (i = 0; i < ncycle; i++) {
00194 relax(p, div, cc,
00195 nu1, nu2, nu3, nu4,
00196 c0, c1, c2, c3, c4,
00197 nx, ny, pa);
00198 bc_scalar(p, nx, ny, NULGRAD2);
00199 }
00200 #else
00201 mglin(div, p, cc, ra, rc, rei, epsilon, nx, ny, ng);
00202 #endif
00203
00204 datbarray(p, nx, ny, "pafter");
00205
00206
00207
00208
00209 for (i = 2; i <= nx - 1; i++) {
00210 for (j = 2; j <= ny - 1; j++)
00211 if (IN(a[i-1][j])) {
00212 if (IN(cc[i][j])) {
00213 p0 = p[i][j];
00214 if (IN(cc[i-1][j])) { p3 = p[i-1][j]; n3 = 1.0; }
00215 else { p3 = pa; n3 = -nu3[i][j]; }
00216 }
00217 else if (IN(cc[i-1][j])) {
00218 p3 = p[i-1][j];
00219 p0 = pa; n3 = nu1[i-1][j];
00220 }
00221 else {
00222 fprintf(stderr, "pressure(): error for u(%d,%d)\n", i, j);
00223 exit(1);
00224 }
00225 u[i][j] -= (p0 - p3)/n3;
00226 }
00227 for (j = 3; j <= ny - 1; j++)
00228 if (IN(c[i][j-1])) {
00229 if (IN(cc[i][j])) {
00230 p0 = p[i][j];
00231 if (IN(cc[i][j-1])) { p4 = p[i][j-1]; n4 = 1.0; }
00232 else { p4 = pa; n4 = -nu4[i][j]; }
00233 }
00234 else if (IN(cc[i][j-1])) {
00235 p4 = p[i][j-1];
00236 p0 = pa; n4 = nu2[i][j-1];
00237 }
00238 else {
00239 fprintf(stderr, "pressure(): error for v(%d,%d)\n", i, j);
00240 exit(1);
00241 }
00242 v[i][j] -= (p0 - p4)/n4;
00243 }
00244 }
00245 }
00246
00247
00248 void coli(real2D cc,
00249 real2D nu1, real2D nu2, real2D nu3, real2D nu4,
00250 real2D c0, real2D c1, real2D c2, real2D c3, real2D c4,
00251 int nx, int ny)
00252 {
00253 int i, j;
00254 real n1, n2, n3, n4, rj, rj12, rj_12;
00255
00256 for (i = 2; i < nx; i++)
00257 for (j = 2; j < ny; j++)
00258 if (IN(cc[i][j])) {
00259 n1 = IN(cc[i+1][j]) ? 1.0 : nu1[i][j];
00260 n2 = IN(cc[i][j+1]) ? 1.0 : nu2[i][j];
00261 n3 = IN(cc[i-1][j]) ? 1.0 : - nu3[i][j];
00262 n4 = IN(cc[i][j-1]) ? 1.0 : - nu4[i][j];
00263
00264 if (n1 < 0.0 || n2 < 0.0 || n3 < 0.0 || n4 < 0.0) {
00265 fprintf(stderr, "coli(): error at %d,%d: n1: %g n2: %g n3: %g n4: %g\n", i, j, n1, n2, n3, n4);
00266 }
00267
00268 rj = (real)j - 1.5;
00269 rj12 = (real)j - 1.0;
00270 rj_12 = (real)j - 2.0;
00271 c0[i][j] = n1*n2*n3*n4*(n2 + n4)/(rj*n2*n4*(n2 + n4) +
00272 n1*n3*(rj12*n4 + rj_12*n2));
00273 c1[i][j] = rj/(n1*(n1 + n3));
00274 c2[i][j] = rj12/(n2*(n2 + n4));
00275 c3[i][j] = rj/(n3*(n1 + n3));
00276 c4[i][j] = rj_12/(n4*(n2 + n4));
00277 }
00278 }
00279
00280
00281 void adaptative(real2D u, real2D v, real2D divafter, real2D cc,
00282 int *npre, int *npost,
00283 real mineps, real maxeps, int nx, int ny)
00284 {
00285 int i, j;
00286 real epsilon, h = 1.0/(nx - 2), hi2;
00287 hi2 = 1.0/(h*h);
00288
00289
00290
00291
00292 for (i = 2; i <= nx - 1; i++)
00293 for (j = 2; j <= ny - 1; j++)
00294 if (IN(cc[i][j]))
00295 divafter[i][j] = (((real)j - 1.)*v[i][j+1] - ((real)j - 2.)*v[i][j] +
00296 ((real)j - 1.5)*(u[i+1][j] - u[i][j]))*hi2;
00297 else
00298 divafter[i][j] = 0.0;
00299
00300
00301
00302 epsilon = rdivmax(divafter, nx, ny);
00303 if (epsilon > mineps) {
00304 (*npre)++; (*npost)++;
00305 }
00306 else if (epsilon < maxeps) {
00307 *npre = MAX(*npre - 1, 1);
00308 *npost = MAX(*npost - 1, 1);
00309 }
00310 }
00311
00312
00313 void adaptative_tau(real2D u, real2D v,
00314 real2D divafter, real2D cc, real2D p,
00315 real *tau,
00316 real mineps, real maxeps, int nx, int ny)
00317 {
00318 int i, j;
00319 real epsilon, velmax, h = 1.0/(nx - 2), hi2;
00320 hi2 = 1./(h*h);
00321
00322
00323
00324
00325 for (i = 2; i <= nx - 1; i++)
00326 for (j = 2; j <= ny - 1; j++)
00327 if (IN(cc[i][j]))
00328 divafter[i][j] = (((real)j - 1.)*v[i][j+1] - ((real)j - 2.)*v[i][j] +
00329 ((real)j - 1.5)*(u[i+1][j] - u[i][j]))*hi2;
00330 else
00331 divafter[i][j] = 0.0;
00332
00333 datbarray(divafter, nx, ny, "divafter");
00334
00335 epsilon = rdivmax(divafter, nx, ny);
00336 velmax = findninf(u, v, nx, ny, &i, &j);
00337 if (epsilon > mineps || velmax > 0.1) {
00338 rescale(u, v, p, 0.5, nx, ny);
00339 *tau *= 0.5;
00340 }
00341 else if (epsilon < maxeps && velmax < 0.05) {
00342 rescale(u, v, p, 2.0, nx, ny);
00343 *tau *= 2.;
00344 }
00345 }
00346
00347
00348 void rescale(real2D u, real2D v, real2D p,
00349 real tscale,
00350 int nx, int ny)
00351 {
00352 int i, j;
00353 real tscale2 = sq(tscale);
00354
00355 for (i = 1; i <= nx; i++)
00356 for (j = 1; j <= ny; j++) {
00357 u[i][j] *= tscale;
00358 v[i][j] *= tscale;
00359 p[i][j] *= tscale2;
00360 }
00361 }
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371