00001 #include <malloc.h>
00002 #include "utilf.h"
00003 #include "markers.h"
00004
00005
00006 #define PERIODIC(i, nx, ip) {ip=(i-2)%(nx-2)+2; if(ip<2) ip+=nx-2;}
00007 #define PERIODIC_DL(dl, nx) {if(fabs(dl)>0.5*(nx-2))\
00008 dl=dl>0.0?dl-nx+2.:dl+nx-2.;}
00009
00010 int interface_arc(interface in, real t)
00011 {
00012 int imin = 0, imax = in.n - 1, i;
00013
00014 if (t < 0.0 || t > in.t[in.n - 1]) return -1;
00015
00016 while(imax - imin > 1) {
00017 i = (imin + imax)/2;
00018 if (t == in.t[i]) return i;
00019 if (t > in.t[i]) imin = i;
00020 else imax = i;
00021 }
00022 return imin;
00023 }
00024
00025
00026 void interface_write_markers(interface in, FILE *fptr)
00027 {
00028 int i;
00029
00030 fprintf(fptr, "\n");
00031 for (i = 0; i <= in.n-1; i++)
00032 fprintf(fptr, "%g %g\n", in.x[i], in.y[i]);
00033 fprintf(fptr, "&\n");
00034 }
00035
00036 void interface_write_markers_speed(real time, interface in, real2D u,
00037 real2D v, real tau, real du,
00038 int nx, int ny, FILE *fptr)
00039 {
00040
00041 int i;
00042 real h=1./(nx-2);
00043
00044 fprintf(fptr, "\n");
00045 for (i = 0; i <= in.n-1; i++)
00046 fprintf(fptr, "%g %g %g %g %g\n", time, in.x[i], in.y[i],
00047 bilinu(u, in.x[i], in.y[i])*du*h/tau,
00048 bilinu(u, in.x[i], in.y[i])*du*h/tau);
00049 fprintf(fptr, "&\n");
00050 }
00051
00052 void interface_write_splines(interface in, FILE *fptr, int nb)
00053 {
00054 int i;
00055 real t;
00056
00057 fprintf(fptr, "\n");
00058 for (i = 0; i < nb; i++) {
00059 t = (real) i * in.t[in.n-1] / (real) (nb - 1);
00060 fprintf(fptr, "%g %g\n",
00061 splint_find(in.t, in.spx, in.n, t),
00062 splint_find(in.t, in.spy, in.n, t));
00063 }
00064 fprintf(fptr, "&\n");
00065 }
00066
00067
00068 void curvature_write(interface in, FILE *fptr)
00069 {
00070 int i;
00071 real x1, y1, dl, kappa;
00072
00073 fprintf(fptr, "\n");
00074 for (i = 0; i < in.n - 1; i++) {
00075 x1 = splint1(in.spx[i], in.t[i]);
00076 y1 = splint1(in.spy[i], in.t[i]);
00077 dl = sqrt(sq(x1) + sq(y1));
00078 kappa = (x1*splint2(in.spy[i], in.t[i]) - y1*splint2(in.spx[i], in.t[i]))
00079 / (dl*dl*dl);
00080 fprintf(fptr, "%g %g\n", in.t[i]/in.t[in.n-1], kappa);
00081 }
00082 }
00083
00084
00085 real interfaces_area(interface *in, int n)
00086 {
00087 int i, j;
00088 real ar = 0.0, a1, a2, a3, a4, a5, a6, t2, t1;
00089 interface in1;
00090
00091 for (j = 0; j < n; j++) {
00092 in1 = in[j];
00093 for (i = 0; i < in1.n - 1; i++)
00094 {
00095 a1 = in1.spx[i].a*in1.spy[i].b;
00096 a2 = 0.5*(in1.spx[i].b*in1.spy[i].b + 2.*in1.spx[i].a*in1.spy[i].c);
00097 a3 = (in1.spx[i].c*in1.spy[i].b + 2.*in1.spx[i].b*in1.spy[i].c
00098 + 3.*in1.spx[i].a*in1.spy[i].d)/3.;
00099 a4 = 0.25*(in1.spx[i].d*in1.spy[i].b + 2.*in1.spx[i].c*in1.spy[i].c
00100 + 3.*in1.spx[i].b*in1.spy[i].d);
00101 a5 = (3.*in1.spx[i].c*in1.spy[i].d + 2.*in1.spx[i].d*in1.spy[i].c)/5.;
00102 a6 = 0.5*in1.spx[i].d*in1.spy[i].d;
00103 t1 = in1.t[i]; t2 = in1.t[i+1];
00104 ar += t2*(a1 + t2*(a2 + t2*(a3 + t2*(a4 + t2*(a5 + t2*a6))))) -
00105 t1*(a1 + t1*(a2 + t1*(a3 + t1*(a4 + t1*(a5 + t1*a6)))));
00106 }
00107 }
00108 return ar;
00109 }
00110
00111
00112 real interfaces_axivolume(interface *in, int n)
00113 {
00114 int i, j;
00115 real ar = 0.0, a1, a2, a3, a4, a5, a6, a7, a8, a9, t2, t1;
00116 real ax, bx, cx, dx, ay, by, cy, dy;
00117 real x1, y1, x2, y2;
00118 interface in1;
00119
00120 for (j = 0; j < n; j++) {
00121 in1 = in[j];
00122 for (i = 0; i < in1.n - 1; i++) {
00123 #ifdef POLYVOLUME
00124
00125 ax = in1.spx[i].a; bx = in1.spx[i].b;
00126 cx = in1.spx[i].c; dx = in1.spx[i].d;
00127 ay = in1.spy[i].a - 2.0; by = in1.spy[i].b;
00128 cy = in1.spy[i].c; dy = in1.spy[i].d;
00129
00130 a1 = ax*ay*by;
00131 a2 = ax*ay*cy+(ax*by+bx*ay)*by/2.;
00132 a3 = ax*ay*dy+2.0/3.0*(ax*by+bx*ay)*cy+(ax*cy+bx*by+cx*ay)*by/3.;
00133 a4 = 3.0/4.0*(ax*by+bx*ay)*dy+(ax*cy+bx*by+cx*ay)*cy/2.
00134 +(ax*dy+bx*cy+cx*by+dx*ay)*by/4.;
00135 a5 = 3.0/5.0*(ax*cy+bx*by+cx*ay)*dy
00136 +2.0/5.0*(ax*dy+bx*cy+cx*by+dx*ay)*cy+(bx*dy+cx*cy+dx*by)*by/5.;
00137 a6 = (ax*dy+bx*cy+cx*by+dx*ay)*dy/2+(bx*dy+cx*cy+dx*by)*cy/3
00138 +(cx*dy+dx*cy)*by/6.;
00139 a7 = 3.0/7.0*(bx*dy+cx*cy+dx*by)*dy+2.0/7.0*(cx*dy+dx*cy)*cy
00140 +dx*dy*by/7.;
00141 a8 = 3.0/8.0*(cx*dy+dx*cy)*dy+dx*dy*cy/4.;
00142 a9 = dx*dy*dy/3.;
00143
00144 t1 = in1.t[i]; t2 = in1.t[i+1];
00145 ar += t2*(a1 + t2*(a2 + t2*(a3 + t2*(a4 + t2*(a5 + t2*(a6 + t2*(a7 + t2*(a8 + t2*a9)))))))) -
00146 t1*(a1 + t1*(a2 + t1*(a3 + t1*(a4 + t1*(a5 + t1*(a6 + t1*(a7 + t1*(a8 + t1*a9))))))));
00147 #else
00148
00149 x1 = in1.x[i]; y1 = in1.y[i] - 2.;
00150 x2 = in1.x[i+1]; y2 = in1.y[i+1] - 2.;
00151 ar += ((x2 - x1)*(y2 - y1)/3. +
00152 (y1*(x2 - x1) + x1*(y2 - y1))/2. + x1*y1)*(y2 - y1);
00153 #endif
00154 }
00155 }
00156 return 2.*PI*ar;
00157 }
00158
00159
00160 real interfaces_xmoment(interface *in, int n)
00161 {
00162
00163
00164 static real coef[7] = {1., 3., 3., 2., 3., 3., 1.};
00165 int i, j, k;
00166 real x, yp, h, t1, t2, t, sum, total = 0.0;
00167 interface in1;
00168 polynom3 px, py;
00169
00170 for (k = 0; k < n; k++) {
00171 in1 = in[k];
00172 for (j = 0; j < in1.n - 1; j++) {
00173 t1 = in1.t[j]; t2 = in1.t[j+1];
00174 px = in1.spx[j]; py = in1.spy[j];
00175 sum = 0.0; h = (t2 - t1)/6.;
00176 for (i = 0; i < 7; i++) {
00177 t = t1 + h*i;
00178 x = splint(px, t) - 2.;
00179 yp = splint1(py, t);
00180 sum += coef[i]*x*x*x*yp;
00181 }
00182 total += 3.*h*sum/8.;
00183 }
00184 }
00185 return total/3.;
00186 }
00187
00188
00189 real interfaces_ymoment(interface *in, int n)
00190 {
00191
00192
00193 static real coef[7] = {1., 3., 3., 2., 3., 3., 1.};
00194 int i, j, k;
00195 real y, xp, h, t1, t2, t, sum, total = 0.0;
00196 interface in1;
00197 polynom3 px, py;
00198
00199 for (k = 0; k < n; k++) {
00200 in1 = in[k];
00201 for (j = 0; j < in1.n - 1; j++) {
00202 t1 = in1.t[j]; t2 = in1.t[j+1];
00203 px = in1.spx[j]; py = in1.spy[j];
00204 sum = 0.0; h = (t2 - t1)/6.;
00205 for (i = 0; i < 7; i++) {
00206 t = t1 + h*i;
00207 y = splint(py, t) - 2.;
00208 xp = splint1(px, t);
00209 sum += coef[i]*y*y*y*xp;
00210 }
00211 total += 3.*h*sum/8.;
00212 }
00213 }
00214 return total/3.;
00215 }
00216
00217
00218 real interfaces_x_amp(interface *in, int n)
00219 {
00220 int i, j;
00221 real max = -1e6, min = 1e6;
00222
00223 for (j = 0; j < n; j++)
00224 for (i = 0; i < in[j].n; i++) {
00225 max = in[j].x[i] > max ? in[j].x[i] : max;
00226 min = in[j].x[i] < min ? in[j].x[i] : min;
00227 }
00228 return fabs(max - min);
00229 }
00230
00231
00232 real interfaces_y_amp(interface *in, int n)
00233 {
00234 int i, j;
00235 real max = -1e6, min = 1e6;
00236
00237 for (j = 0; j < n; j++)
00238 for (i = 0; i < in[j].n; i++) {
00239 max = in[j].y[i] > max ? in[j].y[i] : max;
00240 min = in[j].y[i] < min ? in[j].y[i] : min;
00241 }
00242 return fabs(max - min);
00243 }
00244
00245
00246 void interface_splines(interface in, int nx, int ny)
00247 {
00248 real *d2y, l = 0.0, d0, d1, det, dy0, dy1, yp;
00249 real frac;
00250 int i;
00251
00252 d2y = (real *)malloc(in.n * sizeof(real));
00253
00254 in.t[0] = 0.0;
00255 for (i = 1; i < in.n; i++) {
00256
00257 frac = fabs(modf(in.x[i], &d0));
00258 if (frac < INTERPREC || 1. - frac < INTERPREC ||
00259 fabs(0.5 - frac) < INTERPREC) {
00260 printf("WARNING: interfaces_splines(): moving x[%d]: %.10f to %.10f\n",
00261 i, in.x[i], in.x[i] + 10.*INTERPREC);
00262 in.x[i] += 10.*INTERPREC;
00263 }
00264 frac = fabs(modf(in.y[i], &d0));
00265 if (frac < INTERPREC || 1. - frac < INTERPREC ||
00266 fabs(0.5 - frac) < INTERPREC) {
00267 printf("WARNING: interfaces_splines(): moving y[%d]: %.10f to %.10f\n",
00268 i, in.y[i], in.y[i] + 10.*INTERPREC);
00269 in.y[i] += 10.*INTERPREC;
00270 }
00271
00272 d0 = sqrt(sq(in.x[i] - in.x[i-1]) + sq(in.y[i] - in.y[i-1]));
00273
00274
00275
00276
00277 l += d0;
00278 in.t[i] = l;
00279 }
00280
00281 switch(in.bc) {
00282 case TRUE_PERIODIC:
00283 Pspline(in.t, in.x, d2y, in.t[in.n - 1], in.n - 1, in.spx);
00284 Pspline(in.t, in.y, d2y, in.t[in.n - 1], in.n - 1, in.spy);
00285 break;
00286 case APPROX_PERIODIC:
00287
00288
00289
00290 d0 = in.t[in.n-1] - in.t[in.n-2];
00291 d1 = d0 + in.t[1] - in.t[0];
00292 det = d1*d0*(d0 - d1);
00293
00294 dy0 = in.x[0] - in.x[in.n-2];
00295 dy1 = in.x[1] - in.x[in.n-2];
00296 PERIODIC_DL(dy0, nx);
00297 PERIODIC_DL(dy1, nx);
00298 yp = (2.*(dy0*d1 - dy1*d0)*d0 + dy1*d0*d0 - dy0*d1*d1) / det;
00299 spline(in.t, in.x, in.n, yp, yp, d2y, in.spx, SP_DERIVATIVE);
00300
00301 dy0 = in.y[0] - in.y[in.n-2];
00302 dy1 = in.y[1] - in.y[in.n-2];
00303 yp = (2.*(dy0*d1 - dy1*d0)*d0 + dy1*d0*d0 - dy0*d1*d1) / det;
00304 spline(in.t, in.y, in.n, yp, yp, d2y, in.spy, SP_DERIVATIVE);
00305 break;
00306 case AXITRUE:
00307 spline(in.t, in.x, in.n, 0.0, 0.0, d2y, in.spx, SP_DERIVATIVE);
00308 spline(in.t, in.y, in.n, 1.0, -1.0, d2y, in.spy, SP_DERIVATIVE);
00309 break;
00310 case AXINATURAL:
00311 spline(in.t, in.x, in.n, 0.0, 0.0, d2y, in.spx, SP_NATURAL);
00312 spline(in.t, in.y, in.n, 0.0, 0.0, d2y, in.spy, SP_NATURAL);
00313 break;
00314 case AXIBOTH:
00315 spline(in.t, in.x, in.n, 0.0, 0.0, d2y, in.spx, SP_DERIVATIVE);
00316 spline(in.t, in.y, in.n, 1.0, 1.0, d2y, in.spy, SP_DERIVATIVE);
00317 break;
00318 default:
00319 printf("interface_splines(): bad value for the bc parameter: bc = %d\n", in.bc);
00320 exit(1);
00321 }
00322
00323 free(d2y);
00324 }
00325
00326
00327 void interface_redis(interface *in, real space)
00328 {
00329 int i, j, nb, k = 0;
00330 real l, dl, xe, ye;
00331
00332 nb = (int)(in->t[in->n-1] / space) + 2;
00333 dl = in->t[in->n-1] / (real)(nb - 1);
00334 if (dl >= 1.0)
00335 printf("WARNING interface_redis(): dl=%g\n", dl);
00336
00337 xe = in->x[in->n-1];
00338 ye = in->y[in->n-1];
00339
00340 in->x = (real *)realloc(in->x, nb * sizeof(real));
00341 in->y = (real *)realloc(in->y, nb * sizeof(real));
00342
00343 l = dl;
00344 for (i = 1; i < nb - 1; i++, l += dl) {
00345
00346 while(in->t[k+1] < l)
00347 k++;
00348
00349 #ifdef DEBUG_REDIS
00350 if (k >= in->n-1) {
00351 printf("interface_redis: Error i=%d/%d k too large: %d/%d\n",
00352 i, nb - 1, k, in->n - 1);
00353 exit(1);
00354 }
00355 if (in->t[k] > l || in->t[k+1] < l) {
00356 printf("interface_redis: Error i=%d/%d k=%d, %g <= %g <= %g\n",
00357 i, nb - 1, k, in->t[k], l, in->t[k+1]);
00358 exit(1);
00359 }
00360 #endif
00361
00362 in->x[i] = splint(in->spx[k], l);
00363 in->y[i] = splint(in->spy[k], l);
00364 }
00365
00366 in->x[nb - 1] = xe;
00367 in->y[nb - 1] = ye;
00368 in->t = (real *)realloc(in->t, nb * sizeof(real));
00369 in->spx = (polynom3 *)realloc(in->spx, (nb - 1) * sizeof(polynom3));
00370 in->spy = (polynom3 *)realloc(in->spy, (nb - 1) * sizeof(polynom3));
00371 #ifdef FREE
00372 in->p = (real *)realloc(in->p, nb * sizeof(real));
00373 #endif
00374 in->n = nb;
00375 }
00376
00377
00378 void interface_redis_scale(interface *in, interface src, real space,
00379 real scale)
00380 {
00381 int i, j, nb, k = 0;
00382 real l, dl, xe, ye;
00383
00384 nb = (int)(src.t[src.n-1] / space) + 2;
00385 dl = src.t[src.n-1] / (real)(nb - 1);
00386
00387 in->x = (real *)realloc(in->x, nb * sizeof(real));
00388 in->y = (real *)realloc(in->y, nb * sizeof(real));
00389 in->t = (real *)realloc(in->t, nb * sizeof(real));
00390 in->spx = (polynom3 *)realloc(in->spx, (nb - 1) * sizeof(polynom3));
00391 in->spy = (polynom3 *)realloc(in->spy, (nb - 1) * sizeof(polynom3));
00392 #ifdef FREE
00393 in->p = (real *)realloc(in->p, nb * sizeof(real));
00394 #endif
00395 in->n = nb;
00396
00397 l = dl;
00398 for (i = 1; i < nb - 1; i++, l += dl) {
00399
00400 while(src.t[k+1] < l)
00401 k++;
00402 in->x[i] = scale*(splint(src.spx[k], l) - 2.) + 2.;
00403 in->y[i] = scale*(splint(src.spy[k], l) - 2.) + 2.;
00404 }
00405 in->x[0] = scale*(src.x[0] - 2.) + 2.;
00406 in->y[0] = scale*(src.y[0] - 2.) + 2.;
00407 in->x[nb - 1] = scale*(src.x[src.n - 1] - 2.) + 2.;
00408 in->y[nb - 1] = scale*(src.y[src.n - 1] - 2.) + 2.;
00409 }
00410
00411
00412 void interface_filter(interface *in, int nx, int ny)
00413 {
00414 int i;
00415 real t;
00416
00417 for (i = 0; i < in->n - 1; i++) {
00418 t = (in->t[i] + in->t[i+1])/2.;
00419 in->x[i] = splint(in->spx[i], t);
00420 in->y[i] = splint(in->spy[i], t);
00421 }
00422 in->x[in->n-1] = in->x[0];
00423 in->y[in->n-1] = in->y[0];
00424
00425 interface_splines(*in, nx, ny);
00426 }
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514 void interface_copy(interface *dst, interface in)
00515 {
00516 int l;
00517 dst->x = (real *)malloc(in.n * sizeof(real));
00518 dst->y = (real *)malloc(in.n * sizeof(real));
00519 dst->t = (real *)malloc(in.n * sizeof(real));
00520 dst->spx = (polynom3 *)malloc((in.n - 1) * sizeof(polynom3));
00521 dst->spy = (polynom3 *)malloc((in.n - 1) * sizeof(polynom3));
00522 #ifdef FREE
00523 dst->p = (real *)calloc(in.n, sizeof(real));
00524 #endif
00525 dst->n = in.n;
00526 for (l = 0; l < in.n - 1; l++) {
00527 dst->x[l] = in.x[l];
00528 dst->y[l] = in.y[l];
00529 dst->t[l] = in.t[l];
00530 dst->spx[l] = in.spx[l];
00531 dst->spy[l] = in.spy[l];
00532 }
00533 dst->x[in.n-1] = in.x[in.n-1];
00534 dst->y[in.n-1] = in.y[in.n-1];
00535 dst->t[in.n-1] = in.t[in.n-1];
00536 }
00537
00538
00539 void interface_init(interface *dst)
00540 {
00541 dst->x = (real *)malloc(sizeof(real));
00542 dst->y = (real *)malloc(sizeof(real));
00543 dst->t = (real *)malloc(sizeof(real));
00544 dst->spx = (polynom3 *)malloc(sizeof(polynom3));
00545 dst->spy = (polynom3 *)malloc(sizeof(polynom3));
00546 #ifdef FREE
00547 dst->p = (real *)calloc(1, sizeof(real));
00548 #endif
00549 dst->n = 0;
00550 }
00551
00552
00553 void interface_free(interface in)
00554 {
00555 free(in.x); free(in.y); free(in.t);
00556 free(in.spx); free(in.spy);
00557 #ifdef FREE
00558 free(in.p);
00559 #endif
00560 }
00561
00562
00563 void interface_advect(interface in, real2D u, real2D v,
00564 #ifdef FREE
00565 real2D a, real2D c, real2D cc,
00566 #endif
00567 int nx, int ny)
00568 {
00569 #ifdef BICUB
00570 int i, j, l, ip;
00571 int iuold = -1, juold = -1, ivold = -1, jvold = -1;
00572 real cu[16], cv[16], dx, dy;
00573
00574 for (l = 0; l < in.n; l++)
00575 {
00576 i = in.x[l]; j = (int) ((real) in.y[l] - 0.5);
00577 PERIODIC(i, nx, ip);
00578 if (ip != iuold || j != juold) {
00579 bcucof(u, ip, j, cu, nx, ny);
00580 iuold = ip; juold = j;
00581 }
00582 dx = bcuint(in.x[l] - (real) i, in.y[l] - 0.5 - (real) j, cu);
00583
00584 i = (int) ((real) in.x[l] - 0.5); j = in.y[l];
00585 PERIODIC(i, nx, ip);
00586 if (ip != ivold || j != jvold) {
00587 bcucof(v, ip, j, cv, nx, ny);
00588 ivold = ip; jvold = j;
00589 }
00590 dy = bcuint(in.x[l] - 0.5 - (real) i, in.y[l] - (real) j, cv);
00591
00592 in.x[l] += dx; in.y[l] += dy;
00593 }
00594 #endif
00595 #ifdef BILIN
00596 int i, j, ip, l;
00597 real dx, dy, x, y;
00598
00599 for (l = 0; l < in.n; l++)
00600 {
00601 i = in.x[l]; j = (int) ((real) in.y[l] - 0.5);
00602 PERIODIC(i, nx, ip);
00603 x = in.x[l] - (real) i;
00604 y = in.y[l] - 0.5 - (real) j;
00605 dx = u[ip][j]*(1. - x - y + x*y) + u[ip+1][j]*x*(1. - y) +
00606 u[ip][j+1]*y*(1. - x) + u[ip+1][j+1]*x*y;
00607
00608 i = (int) ((real) in.x[l] - 0.5); j = in.y[l];
00609 PERIODIC(i, nx, ip);
00610 x = in.x[l] - 0.5 - (real) i;
00611 y = in.y[l] - (real) j;
00612 dy = v[ip][j]*(1. - x - y + x*y) + v[ip+1][j]*x*(1. - y) +
00613 v[ip][j+1]*y*(1. - x) + v[ip+1][j+1]*x*y;
00614
00615 #ifdef AXI
00616
00617 if (l > 0 && l < in.n - 1)
00618 in.y[l] += dy;
00619 in.x[l] += dx;
00620 #else
00621 in.x[l] += dx; in.y[l] += dy;
00622 #endif
00623 }
00624 #endif
00625 #ifdef FREE
00626 int l;
00627 real dx, dy;
00628 #ifdef AXI
00629 int i, j, ip;
00630 real x, y;
00631
00632
00633 i = in.x[0]; j = (int) ((real) in.y[0] - 0.5);
00634 PERIODIC(i, nx, ip);
00635 x = in.x[0] - (real) i;
00636 y = in.y[0] - 0.5 - (real) j;
00637 in.x[0] += u[ip][j]*(1. - x - y + x*y) + u[ip+1][j]*x*(1. - y) +
00638 u[ip][j+1]*y*(1. - x) + u[ip+1][j+1]*x*y;
00639
00640 for (l = 1; l < in.n - 1; l++)
00641 {
00642 i = in.x[l]; j = (int) ((real) in.y[l] - 0.5);
00643 PERIODIC(i, nx, ip);
00644 x = in.x[l] - (real) i;
00645 y = in.y[l] - 0.5 - (real) j;
00646 dx = u[ip][j]*(1. - x - y + x*y) + u[ip+1][j]*x*(1. - y) +
00647 u[ip][j+1]*y*(1. - x) + u[ip+1][j+1]*x*y;
00648
00649 i = (int) ((real) in.x[l] - 0.5); j = in.y[l];
00650 PERIODIC(i, nx, ip);
00651 x = in.x[l] - 0.5 - (real) i;
00652 y = in.y[l] - (real) j;
00653 dy = v[ip][j]*(1. - x - y + x*y) + v[ip+1][j]*x*(1. - y) +
00654 v[ip][j+1]*y*(1. - x) + v[ip+1][j+1]*x*y;
00655
00656 in.x[l] += dx; in.y[l] += dy;
00657 }
00658
00659 i = in.x[in.n-1]; j = (int) ((real) in.y[in.n-1] - 0.5);
00660 PERIODIC(i, nx, ip);
00661 x = in.x[in.n-1] - (real) i;
00662 y = in.y[in.n-1] - 0.5 - (real) j;
00663 in.x[in.n-1] += u[ip][j]*(1. - x - y + x*y) + u[ip+1][j]*x*(1. - y) +
00664 u[ip][j+1]*y*(1. - x) + u[ip+1][j+1]*x*y;
00665
00666 #else
00667 real xn, yn, dl;
00668
00669 xn = in.y[in.n-2] - in.y[1];
00670 yn = in.x[1] - in.x[in.n-2];
00671 dl = sqrt(sq(xn) + sq(yn));
00672 xn /= dl; yn /= dl;
00673 dx = linear(u, a, in.x[0], in.y[0], xn, yn, bilin_u);
00674 dy = linear(v, c, in.x[0], in.y[0], xn, yn, bilin_v);
00675
00676
00677
00678
00679 in.x[0] += dx; in.y[0] += dy;
00680
00681 for (l = 1; l < in.n - 1; l++) {
00682
00683
00684 xn = in.y[l-1] - in.y[l+1];
00685
00686 yn = in.x[l+1] - in.x[l-1];
00687 dl = sqrt(sq(xn) + sq(yn));
00688 xn /= dl; yn /= dl;
00689
00690 dx = linear(u, a, in.x[l], in.y[l], xn, yn, bilin_u);
00691 dy = linear(v, c, in.x[l], in.y[l], xn, yn, bilin_v);
00692
00693
00694
00695
00696 in.x[l] += dx; in.y[l] += dy;
00697 }
00698 in.x[in.n-1] = in.x[0];
00699 in.y[in.n-1] = in.y[0];
00700 #endif
00701 #endif
00702 }
00703
00704
00705 static void intersec_update(intersec *in1, intersec *in2, int o, int j)
00706 {
00707 if (in2->n == -1) {
00708 in2->j2[0] = j; in2->in[0] = o;
00709 }
00710 else {
00711 in2->j2[in2->n - 1] = j; in2->in[in2->n - 1] = o;
00712 }
00713
00714 if (in1->n == -1) {
00715 in1->j1[0] = j; in1->in[0] = o;
00716 in1->n = 1;
00717 }
00718 else {
00719 in1->in[in1->n] = o;
00720 in1->j1[in1->n++] = j;
00721 }
00722 }
00723
00724
00725 #ifdef AXI
00726 real stensionaxix(polynom3 px, polynom3 py, real t1, real t2)
00727 {
00728
00729 static real coef[7] = {1., 3., 3., 2., 3., 3., 1.};
00730 int i;
00731 real xp, yp, y, h = (t2 - t1)/6., t, sum = 0.0;
00732
00733 for (i = 0; i < 7; i++) {
00734 t = t1 + h*i;
00735 xp = splint1(px, t);
00736 yp = splint1(py, t);
00737 y = splint(py, t) - 2.;
00738
00739 if (fabs(y) <= 0.01)
00740 sum += coef[i]*splint2(px, t)/sqrt(xp*xp + yp*yp);
00741 else
00742 sum += coef[i]*xp*yp/(y*sqrt(xp*xp + yp*yp));
00743 }
00744 return 3.*h*sum/8.;
00745 }
00746
00747
00748 real stensionaxiy(polynom3 px, polynom3 py, real t1, real t2)
00749 {
00750
00751 static real coef[7] = {1., 3., 3., 2., 3., 3., 1.};
00752 int i;
00753 real xp, yp, y, h = (t2 - t1)/6., t, sum = 0.0;
00754
00755 for (i = 0; i < 7; i++) {
00756 t = t1 + h*i;
00757 xp = splint1(px, t);
00758 yp = splint1(py, t);
00759 y = splint(py, t) - 1.5;
00760
00761 if (fabs(y) <= 0.01)
00762 sum -= coef[i]*splint2(px, t)*xp/(yp*sqrt(xp*xp + yp*yp));
00763 else
00764 sum -= coef[i]*xp*xp/(y*sqrt(xp*xp + yp*yp));
00765 }
00766 return 3.*h*sum/8.;
00767 }
00768 #endif
00769
00770
00771 void interface_to_c(interface *in, int nint,
00772 #ifdef RECON
00773 intersec **inter,
00774 #endif
00775 real2D work, real2D c, real xo, real yo,
00776 int nx, int ny, int sflag,
00777 real2D rhox, real2D p, real sigma, real tau)
00778 {
00779 int i, ip, ip1, ip2, j, k, l, m, o;
00780 int n, nin;
00781 real a, a1, a2, a3, a4, a5, a6, ti[14], t, t1, t2;
00782 real x, y, y1, dx, dy, h;
00783 polynom3 px, py;
00784 typedef struct {
00785 real t;
00786 int type, coord;
00787 } listinter;
00788 listinter listi[14], xl;
00789
00790 h = 1.0 / (nx - 2);
00791 sigma *= tau * tau / (h * h * h);
00792
00793
00794 for (i = 2; i < nx; i++)
00795 for (j = 2; j < ny; j++) {
00796 #ifdef RECON
00797 inter[i][j].n = 0;
00798 #endif
00799 work[i][j] = 0.0;
00800 }
00801
00802
00803 for (o = 0; o < nint; o++)
00804
00805 for (l = 0; l < in[o].n - 1; l++)
00806 {
00807
00808 i = (real)(in[o].x[l] - xo);
00809 j = (real)(in[o].y[l] - yo);
00810 t1 = in[o].t[l]; t2 = in[o].t[l+1];
00811 px = in[o].spx[l]; py = in[o].spy[l];
00812 px.a -= xo; py.a -= yo;
00813
00814
00815 listi[0].t = t1; listi[0].type = MARK_TYPE;
00816 nin = 1;
00817
00818
00819 n = polyroots(py, t1, t2, ti, (real) j, INTERPREC);
00820 for (k = 0; k < n; k++) {
00821 listi[nin].t = ti[k]; listi[nin].type = HOR_TYPE;
00822 listi[nin++].coord = j;
00823 }
00824 n = polyroots(py, t1, t2, ti, (real) j + 1.0, INTERPREC);
00825 for (k = 0; k < n; k++) {
00826 listi[nin].t = ti[k]; listi[nin].type = HOR_TYPE;
00827 listi[nin++].coord = j + 1;
00828 }
00829
00830 n = polyroots(px, t1, t2, ti, (real) i, INTERPREC);
00831 for (k = 0; k < n; k++) {
00832 listi[nin].t = ti[k]; listi[nin].type = VER_TYPE;
00833 listi[nin++].coord = i;
00834 }
00835 n = polyroots(px, t1, t2, ti, (real) i + 1.0, INTERPREC);
00836 for (k = 0; k < n; k++) {
00837 listi[nin].t = ti[k]; listi[nin].type = VER_TYPE;
00838 listi[nin++].coord = i + 1;
00839 }
00840
00841
00842 listi[nin].t = t2; listi[nin++].type = MARK_TYPE;
00843
00844
00845 for (k = 1; k < nin; k++) {
00846 xl = listi[k]; i = k - 1;
00847 while (i >= 0 && listi[i].t > xl.t) {
00848 listi[i + 1] = listi[i]; i--;
00849 }
00850 listi[i + 1] = xl;
00851 }
00852
00853
00854 a1 = px.a*py.b;
00855 a2 = 0.5*(px.b*py.b + 2.*px.a*py.c);
00856 a3 = (px.c*py.b + 2.*px.b*py.c + 3.*px.a*py.d)/3.;
00857 a4 = 0.25*(px.d*py.b + 2.*px.c*py.c + 3.*px.b*py.d);
00858 a5 = (3.*px.c*py.d + 2.*px.d*py.c)/5.;
00859 a6 = 0.5*px.d*py.d;
00860
00861 for (k = 0; k < nin - 1; k++)
00862 {
00863 t1 = listi[k].t; t2 = listi[k+1].t;
00864 t = 0.5*(t1 + t2);
00865 i = splint(px, t);
00866 j = splint(py, t);
00867
00868 x = splint(px, t1);
00869 y = splint(py, t1);
00870
00871
00872 if (listi[k].type == VER_TYPE) {
00873
00874 if (listi[k].coord == i) {
00875 t = y - j - 1.0; m = -1;
00876 PERIODIC(i, nx, ip);
00877 work[ip][j] += t*ip;
00878 PERIODIC(i - 1, nx, ip1);
00879 work[ip1][j] -= t*(ip1 + 1);
00880 }
00881 else {
00882 t = y - j; m = 1;
00883 PERIODIC(i, nx, ip);
00884 work[ip][j] += t*(ip + 1);
00885 PERIODIC(i + 1, nx, ip1);
00886 work[ip1][j] -= t*ip1;
00887 }
00888
00889
00890 #ifdef RECON
00891 if (inter[ip][j].n >= NSEC)
00892 printf("WARNING intersec_update: inter[%d][%d].n = %d\n",
00893 ip, j, inter[ip][j].n);
00894 else
00895 intersec_update(&inter[ip][j], &inter[ip1][j], o, l);
00896 #endif
00897
00898
00899 switch(sflag) {
00900 case TENSION_U:
00901 dx = splint1(px, t1); dy = splint1(py, t1);
00902 a = sigma*dx / sqrt(dx*dx + dy*dy);
00903 PERIODIC(i + 1, nx, ip);
00904 rhox[ip][j] -= a;
00905 PERIODIC(i + m + 1, nx, ip1);
00906 rhox[ip1][j] += a;
00907
00908 a = y - (real) j;
00909 if (m == 1) {
00910 if (a > 0.5)
00911 a = (1.0 - a)*(p[ip][j+1] - p[ip][j]);
00912 else
00913 a = a*(p[ip][j-1] - p[ip][j]);
00914 rhox[ip][j] -= a;
00915 rhox[ip1][j] += a;
00916 }
00917 else {
00918 PERIODIC(i, nx, ip2);
00919 if (a > 0.5)
00920 a = (1.0 - a)*(p[ip2][j+1] - p[ip2][j]);
00921 else
00922 a = a*(p[ip2][j-1] - p[ip2][j]);
00923 rhox[ip][j] += a;
00924 rhox[ip1][j] -= a;
00925 }
00926 break;
00927 case TENSION_V:
00928 dx = splint1(px, t1); dy = splint1(py, t1);
00929 a = sigma*dy / sqrt(dx*dx + dy*dy);
00930 rhox[ip][j + 1] -= a;
00931 rhox[ip1][j + 1] += a;
00932 break;
00933 }
00934 }
00935
00936
00937 if (listi[k].type == HOR_TYPE) {
00938 if (listi[k].coord == j)
00939 m = -1;
00940 else
00941 m = 1;
00942
00943
00944 PERIODIC(i, nx, ip);
00945 #ifdef RECON
00946 if (inter[ip][j].n >= NSEC)
00947 printf("WARNING intersec_update: inter[%d][%d].n = %d\n",
00948 ip, j, inter[ip][j].n);
00949 else
00950 intersec_update(&inter[ip][j], &inter[ip][j + m], o, l);
00951 #endif
00952
00953
00954 switch(sflag) {
00955 case TENSION_U:
00956 dx = splint1(px, t1); dy = splint1(py, t1);
00957 a = sigma*dx / sqrt(dx*dx + dy*dy);
00958 PERIODIC(i + 1, nx, ip);
00959 rhox[ip][j] -= a;
00960 rhox[ip][j + m] += a;
00961 break;
00962 case TENSION_V:
00963 dx = splint1(px, t1); dy = splint1(py, t1);
00964 a = sigma*dy / sqrt(dx*dx + dy*dy);
00965 rhox[ip][j + 1] -= a;
00966 rhox[ip][j + m + 1] += a;
00967
00968 a = x - (real) i;
00969 if (m == 1) {
00970 if (a > 0.5) {
00971 PERIODIC(i + 1, nx, ip1);
00972 a = (1.0 - a)*(p[ip1][j+1] - p[ip][j+1]);
00973 }
00974 else {
00975 PERIODIC(i - 1, nx, ip1);
00976 a = a*(p[ip1][j+1] - p[ip][j+1]);
00977 }
00978 rhox[ip][j + 1] -= a;
00979 rhox[ip][j + 2] += a;
00980 }
00981 else {
00982 if (a > 0.5) {
00983 PERIODIC(i + 1, nx, ip1);
00984 a = (1.0 - a)*(p[ip1][j] - p[ip][j]);
00985 }
00986 else {
00987 PERIODIC(i - 1, nx, ip1);
00988 a = a*(p[ip1][j] - p[ip][j]);
00989 }
00990 rhox[ip][j + 1] += a;
00991 rhox[ip][j] -= a;
00992 }
00993 break;
00994 }
00995 }
00996
00997 #ifdef AXI
00998
00999 switch(sflag) {
01000 case TENSION_U:
01001 PERIODIC(i + 1, nx, ip);
01002 rhox[ip][j] += sigma*stensionaxix(px, py, t1, t2);
01003 break;
01004 case TENSION_V:
01005 PERIODIC(i, nx, ip);
01006 rhox[ip][j+1] += sigma*stensionaxiy(px, py, t1, t2);
01007 break;
01008 }
01009 #endif
01010 PERIODIC(i, nx, ip);
01011
01012 work[ip][j] +=
01013 t2*(a1 + t2*(a2 + t2*(a3 + t2*(a4 + t2*(a5 + t2*a6))))) -
01014 t1*(a1 + t1*(a2 + t1*(a3 + t1*(a4 + t1*(a5 + t1*a6)))));
01015 a = ip - i;
01016
01017 if (a != 0.0)
01018 work[ip][j] += a*(t2*(py.b + t2*(py.c + t2*py.d)) -
01019 t1*(py.b + t1*(py.c + t1*py.d)));
01020 #ifdef RECON
01021 if (inter[ip][j].n == 0)
01022 inter[ip][j].n = -1;
01023 #endif
01024 }
01025 }
01026
01027
01028 for (i = 2; i < nx; i++)
01029 for (j = 2; j < ny; j++)
01030 {
01031 work[i][j] = modf(work[i][j], &y);
01032 if (work[i][j] >= c[i][j] + 0.5)
01033 work[i][j] -= 1.0;
01034 if (work[i][j] <= c[i][j] - 0.5)
01035 work[i][j] += 1.0;
01036 if (work[i][j] <= c[i][j] - 0.5)
01037 work[i][j] += 1.0;
01038
01039
01040 #ifdef LIMITERS
01041 c[i][j] = work[i][j] > 1.0 ? 1.0 : work[i][j] < 0.0 ? 0.0 : work[i][j];
01042 #else
01043 c[i][j] = work[i][j];
01044 #endif
01045 }
01046 }
01047
01048 void interface_reconnect(interface *in, int nint, intersec **inter,
01049 int nx, int ny)
01050 {
01051 int i, j, i1, i2;
01052 int j11, j12, j21, j22;
01053 real t11, t12, t21, t22;
01054
01055 for (i = 2; i < nx; i++)
01056 for (j = 2; j < ny; j++) {
01057 if (inter[i][j].n > 1 && inter[i][j].in[0] != inter[i][j].in[1]) {
01058 i1 = inter[i][j].in[0];
01059 i2 = inter[i][j].in[1];
01060 j11 = inter[i][j].j1[0];
01061 j12 = inter[i][j].j2[0];
01062 j21 = inter[i][j].j1[1];
01063 j22 = inter[i][j].j2[1];
01064 printf("inter[%d][%d].n: %d interfaces: %d %d (%d,%d)(%d,%d)\n",
01065 i, j, inter[i][j].n, i1, i2, j11, j12, j21, j22);
01066 }
01067 }
01068 }
01069
01070
01071 real interface_inside(interface in, real x, real y)
01072 {
01073 int i;
01074 real a, d, dmin = 1e30;
01075 for (i = 0; i < in.n - 1; i++) {
01076 d = sqrt(sq(x - 0.5*(in.x[i] + in.x[i+1])) +
01077 sq(y - 0.5*(in.y[i] + in.y[i+1])));
01078 a = (in.x[i+1] - in.x[i])*(y - in.y[i]) -
01079 (x - in.x[i])*(in.y[i+1] - in.y[i]);
01080 if (d < fabs(dmin)) dmin = a >= 0.0 ? d : -d;
01081 }
01082 if (dmin >= 0.0) return dmin;
01083 return 0.0;
01084 }
01085
01086
01087 void interface_fill(interface *in, int nin, real2D ap, int nx, int ny)
01088 {
01089 int i, j, k;
01090
01091 fill0(ap, nx, ny);
01092 for (i = 2; i <= nx; i++)
01093 for (j = 2; j <= ny; j++)
01094 for (k = 0; k < nin; k++)
01095 if (interface_inside(in[k], (real)i, (real)j)) {
01096 ap[i][j] += 0.25; ap[i-1][j] += 0.25;
01097 ap[i][j-1] += 0.25; ap[i-1][j-1] += 0.25;
01098 }
01099 for (j = 2; j <= ny; j++)
01100 for (k = 0; k < nin; k++)
01101 if (interface_inside(in[k], 1.0, (real)j)) {
01102 ap[1][j] += 0.25; ap[1][j-1] += 0.25;
01103 }
01104 for (i = 2; i <= nx; i++)
01105 for (k = 0; k < nin; k++)
01106 if (interface_inside(in[k], (real)i, 1.0)) {
01107 ap[i][1] += 0.25; ap[i-1][1] += 0.25;
01108 }
01109 }
01110
01111
01112 int interface_split_axis(interface **inlist, real length)
01113 {
01114 interface *in = *inlist;
01115 int i;
01116 for (i = 2; i < in->n - 2; i++)
01117 if (in->y[i] - 2.0 < length) {
01118
01119 interface *newin;
01120 int j;
01121 real x0, y0, x1, y1, x2, y2;
01122 *inlist = (interface *)realloc(*inlist, sizeof(interface)*2);
01123 in = &((*inlist)[0]);
01124 newin = &((*inlist)[1]);
01125 newin->n = in->n - i;
01126 newin->x = (real *)malloc(newin->n * sizeof(real));
01127 newin->y = (real *)malloc(newin->n * sizeof(real));
01128 newin->t = (real *)malloc(newin->n * sizeof(real));
01129 newin->spx = (polynom3 *)malloc((newin->n - 1) * sizeof(polynom3));
01130 newin->spy = (polynom3 *)malloc((newin->n - 1) * sizeof(polynom3));
01131 newin->x[0] = in->x[i+1];
01132 newin->y[0] = 1.999;
01133 for (j = i + 1; j < in->n; j++) {
01134 newin->x[j - i] = in->x[j];
01135 newin->y[j - i] = in->y[j];
01136 }
01137 newin->bc = AXIBOTH;
01138 printf("newin->n: %d i: %d\n", newin->n, i);
01139
01140 in->x[i] = in->x[i-1];
01141 in->y[i] = 1.999;
01142 in->n = i + 1;
01143 in->bc = AXITRUE;
01144 {
01145 FILE *fptr = fopen("old", "wt");
01146 for (i = 0; i < in->n; i++)
01147 fprintf(fptr, "%g %g\n", in->x[i], in->y[i]);
01148 fclose(fptr);
01149 fptr = fopen("new", "wt");
01150 for (i = 0; i < newin->n; i++)
01151 fprintf(fptr, "%g %g\n", newin->x[i], newin->y[i]);
01152 fclose(fptr);
01153 }
01154 return 2;
01155 }
01156 return 1;
01157 }
01158
01159
01160 int interface_merge_axis(interface **inlist, real length)
01161 {
01162 interface *right = *inlist, *left = &((*inlist)[1]);
01163 if (right->x[right->n - 1] - left->x[0] < length) {
01164 int i, n = right->n + left->n - 2;
01165 right->x = (real *)realloc(right->x, n * sizeof(real));
01166 right->y = (real *)realloc(right->y, n * sizeof(real));
01167 right->t = (real *)realloc(right->t, n * sizeof(real));
01168 right->spx = (polynom3 *)realloc(right->spx, (n - 1) * sizeof(polynom3));
01169 right->spy = (polynom3 *)realloc(right->spy, (n - 1) * sizeof(polynom3));
01170 for (i = 1; i < left->n; i++) {
01171 right->x[right->n + i - 2] = left->x[i];
01172 right->y[right->n + i - 2] = left->y[i];
01173 }
01174 right->n = n;
01175 right->bc = AXIBOTH;
01176 interface_free(*left);
01177 {
01178 FILE *fptr = fopen("merged", "wt");
01179 for (i = 0; i < right->n; i++)
01180 fprintf(fptr, "%g %g\n", right->x[i], right->y[i]);
01181 fclose(fptr);
01182 }
01183 return 1;
01184 }
01185 return 2;
01186 }
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222 void interface_axisymmetry(interface *in, real space, int nx, int ny)
01223 {
01224 int i, k, nb = 2 * (in->n - 1) , nold = in->n, n, nnew;
01225 real t, ts, te, ti[4], xe, xs, l, dl, temp;
01226 char old_bc = in->bc;
01227
01228 if (in->x[2] != in->x[1]){
01229 in->x[0] = (sq(in->y[2]-2.)-sq(in->y[1]-2.)+
01230 sq(in->x[2])-sq(in->x[1])) /
01231 (2. * (in->x[2]-in->x[1]));
01232 temp = in->x[0];
01233 if (in->x[1] > in->x[2])
01234 in->x[0] += sqrt(sq(in->y[1]-2.) + sq(in->x[1] - temp));
01235 else
01236 in->x[0] -= sqrt(sq(in->y[1]-2.) + sq(in->x[1] - temp));
01237 }
01238 else in->x[0] = in->x[1];
01239
01240 interface_splines(*in, nx, ny);
01241
01242 interface_redis(in, space);
01243
01244 }
01245
01246
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305
01306
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329
01330
01331
01332
01333
01334
01335
01336
01337
01338
01339
01340
01341
01342
01343
01344
01345
01346
01347
01348
01349
01350
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360
01361
01362
01363
01364
01365
01366