Main Page   Data Structures   File List   Data Fields   Globals  

markers.c

Go to the documentation of this file.
00001 #include <malloc.h>
00002 #include "utilf.h"
00003 #include "markers.h"
00004 
00005 /* Periodic conditions for the index i on a nx grid */
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 /* Physical velocity*/
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       /* integration of xy dy along the polynomial segment */
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       /* integration of xy dy along the segment */
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   /* compute Sum{x^2.dx.dy} */
00163   /* coefficients of Newton-Cotes formula */
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   /* compute Sum{y^2.dx.dy} */
00192   /* coefficients of Newton-Cotes formula */
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     /* Move slightly the points when they are near the grid lines */
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     if (d0 >= 1.0)
00275       printf("WARNING: interfaces_splines(): d0=%f >= 1.0\n", d0);
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     /* We need an estimate of the derivative for the periodic ends 
00288        We suppose a 2nd order interpolation for the points 1, 0, n-2
00289        will do */
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];  /* saving the coordinates of the last point */
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;               /* Starting at i=1 the first point is unchanged */
00344   for (i = 1; i < nb - 1; i++, l += dl) {
00345     /* find the next interval [j;j+1] such as t[j] <= l <= t[j+1] */
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;  /* The last point is unchanged */
00367   in->y[nb - 1] = ye;  /* Copying the saved coordinates */
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;               /* Starting at i=1 the first point is unchanged */
00398   for (i = 1; i < nb - 1; i++, l += dl) {
00399     /* find the next interval [j;j+1] such as t[j] <= l <= t[j+1] */
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 /*cld
00429 void interface_axisymmetry(interface *in, real space, int nx, int ny)
00430 {
00431   int i, k, nb = 2 * (in->n - 1) + 1, nold = in->n, n, nnew;
00432   real t, ts, te, ti[4], xe, xs, l, dl;
00433   char old_bc = in->bc;
00434 
00435   if (in->bc == TRUE_PERIODIC || in->bc == APPROX_PERIODIC) {
00436     interface_filter(in, nx, ny);
00437     interface_redis(in, space);
00438     return;
00439   }
00440 
00441   in->x = (real *)realloc(in->x, nb * sizeof(real));
00442   in->y = (real *)realloc(in->y, nb * sizeof(real));
00443   in->t = (real *)realloc(in->t, nb * sizeof(real));
00444   in->spx = (polynom3 *)realloc(in->spx, (nb - 1) * sizeof(polynom3));
00445   in->spy = (polynom3 *)realloc(in->spy, (nb - 1) * sizeof(polynom3));
00446 
00447   for (i = 0; i < in->n - 1; i++) {
00448     t = (in->t[i] + in->t[i+1])/2.;
00449     in->x[i] = splint(in->spx[i], t);
00450     in->y[i] = splint(in->spy[i], t);
00451   }
00452   for (i = in->n - 1; i < nb - 1; i++) {
00453     in->x[i] = in->x[nb - 2 - i];
00454     in->y[i] = 4. - in->y[nb - 2 - i];
00455   }
00456   in->x[nb-1] = in->x[0]; in->y[nb-1] = in->y[0];
00457   in->n = nb;
00458   in->bc = TRUE_PERIODIC;
00459   
00460   interface_splines(*in, nx, ny);
00461   n = polyroots(in->spy[nb-2], in->t[nb-2], in->t[nb-1], 
00462                 ti, 2.0, INTERPREC);
00463   if (n != 1) {
00464     FILE *fptr = fopen("aximarkers", "wt");
00465     interface_write_markers(*in, fptr);
00466     fclose(fptr);
00467     printf("ERROR: interface_axisymmetry(): n = %d\n", n);    
00468     exit(1);
00469   }
00470   xs = splint(in->spx[nb-2], ti[0]);
00471   ts = ti[0] - in->t[nb-1];
00472   n = polyroots(in->spy[nold-2], in->t[nold-2], in->t[nold-1], 
00473                 ti, 2.0, INTERPREC);
00474   if (n != 1) {
00475     FILE *fptr = fopen("aximarkers", "wt");
00476     interface_write_markers(*in, fptr);
00477     fclose(fptr);
00478     printf("ERROR: interface_axisymmetry(): n = %d\n", n);
00479     exit(1);
00480   }
00481   xe = splint(in->spx[nold-2], ti[0]);
00482   te = ti[0];
00483   nnew = (int)((te - ts)/space) + 2;
00484   if (nnew % 2) nnew++;
00485   dl = (te - ts)/(real)(nnew - 1);
00486   if (dl >= 1.0)
00487     printf("WARNING interface_redis(): dl=%g\n", dl);
00488 
00489   in->x = (real *)realloc(in->x, nnew * sizeof(real));
00490   in->y = (real *)realloc(in->y, nnew * sizeof(real));
00491 
00492   l = ts + dl; k = 0;
00493   if (l < 0.0) printf("interface_axisymmetry(): l = %g\n", l);
00494   for (i = 1; i < nnew - 1; i++, l += dl) {
00495     /* find the next interval [j;j+1] such as t[j] <= l <= t[j+1] 
00496     while(in->t[k+1] < l)
00497       k++;
00498     in->x[i] = splint(in->spx[k], l);
00499     in->y[i] = splint(in->spy[k], l);
00500   }
00501   in->x[0] = xs; in->y[0] = 1.9999;
00502   in->x[nnew-1] = xe; in->y[nnew-1] = 1.9999;
00503   in->t = (real *)realloc(in->t, nnew * sizeof(real));
00504   in->spx = (polynom3 *)realloc(in->spx, (nnew - 1) * sizeof(polynom3));
00505   in->spy = (polynom3 *)realloc(in->spy, (nnew - 1) * sizeof(polynom3));
00506 #ifdef FREE
00507   in->p = (real *)realloc(in->p, nnew * sizeof(real));
00508 #endif
00509   in->n = nnew;
00510   in->bc = old_bc;
00511 }
00512 cld*/
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       /* Don't move the first and last markers vertically */
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   /* Don't move the first marker vertically */
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   /* Don't move the last marker vertically */
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     dx = interplate_u(u, a, cc, in.x[0], in.y[0], nx, ny, INTERPLATE_INTER);
00677     dy = interplate_v(v, c, cc, in.x[0], in.y[0], nx, ny, INTERPLATE_INTER);
00678   */
00679   in.x[0] += dx; in.y[0] += dy;
00680 
00681   for (l = 1; l < in.n - 1; l++) {
00682     
00683     /* xn = -splint1(in.spy[l], in.t[l]); */
00684       xn = in.y[l-1] - in.y[l+1];
00685       /*      yn = splint1(in.spx[l], in.t[l]); */
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     dx = interplate_u(u, a, cc, in.x[l], in.y[l], nx, ny, INTERPLATE_INTER);
00694     dy = interplate_v(v, c, cc, in.x[l], in.y[l], nx, ny, INTERPLATE_INTER);
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   /* coefficients of Newton-Cotes formula */
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.; /* Position of the curve relative to the axis of 
00738                                symetry: y = splint(py, t) + yo - 2 */
00739     if (fabs(y) <= 0.01) /* second order approximation near the axis */
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   /* coefficients of Newton-Cotes formula */
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; /* Position of the curve relative to the axis of 
00760                                  symetry: y = splint(py, t) + yo - 2 */
00761     if (fabs(y) <= 0.01) /* second order approximation near the axis */
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   /* No intersections, no volume fraction */
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   /* For each interface */
00803   for (o = 0; o < nint; o++)
00804     /* For each segment */  
00805     for (l = 0; l < in[o].n - 1; l++)
00806       {
00807          /* the positions are shifted (-xo, -yo) */
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         /* first point */
00815         listi[0].t = t1; listi[0].type = MARK_TYPE;
00816         nin = 1;
00817         
00818         /* intersections with the horizontals */
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         /* intersections with the verticals */
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         /* last point */
00842         listi[nin].t = t2; listi[nin++].type = MARK_TYPE;
00843         
00844         /* sort the intersections in ascending order for t */
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         /* coefficients for the computation of the circulation */
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             /* Intersection with the verticals */
00872             if (listi[k].type == VER_TYPE) {
00873               /* add the circulation of the vertical segment */     
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               /* update the intersections structure */
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               /* Add the surface tension term and the pressure
00898                  gradient correction term */
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                 /* pressure gradient correction */
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             /* Intersection with the horizontals */
00937             if (listi[k].type == HOR_TYPE) { 
00938               if (listi[k].coord == j)
00939                 m = -1;
00940               else
00941                 m = 1;
00942               
00943               /* update the intersections structure */
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               /* Add the surface tension term and the pressure gradient
00953                  correction term */
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                 /* pressure gradient correction */
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             /* add the axisymetric contribution to the surface tension */
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             /* add the circulation along the polynomial segment */
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; /* we shift the polynom by a to insure the
01016                            periodicity of the circulation */
01017             if (a != 0.0) /* correction if periodic */
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   /* magic formula */
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         /* limiters used to avoid round-off error problems */
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       /* new interface */
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       /* trim old interface */
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 int interface_merge_axis2(interface **inlist, real length)
01190 {
01191   interface *temp
01192   interface *right = *inlist, *left = &((*inlist)[1]);
01193   if (right->x[0] - left->x[0] < length) {
01194     int i, n = right->n + left->n - 2;
01195     temp->x = (real *)malloc(temp->x, n * sizeof(real));
01196     temp->y = (real *)malloc(temp->y, n * sizeof(real));
01197     temp->t = (real *)malloc(temp->t, n * sizeof(real));
01198     temp->spx = (polynom3 *)malloc(temp->spx, (n - 1) * sizeof(polynom3));
01199     temp->spy = (polynom3 *)malloc(temp->spy, (n - 1) * sizeof(polynom3));
01200     for (i = 0; i < left->n ; i++) {
01201       temp->x[i] = left->x[i];
01202       temp->y[i] = left->y[i];
01203     }
01204     right->n = n;
01205     right->bc = AXIBOTH;
01206     interface_free(*left);
01207     {
01208       FILE *fptr = fopen("merged", "wt");
01209       for (i = 0; i < right->n; i++)
01210       fprintf(fptr, "%g %g\n", right->x[i], right->y[i]);
01211       fclose(fptr);
01212       }
01213     return 1;
01214     }
01215     return 2;
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 /*cld
01249 void interface_axisymmetry(interface *in, real space, int nx, int ny)
01250 {
01251   int i, k, nb = 2 * (in->n - 1) - 2, nold = in->n, n, nnew;
01252   real t, ts, te, ti[4], xe, xs, l, dl, xold, yold;
01253   real1D tempx, tempy;
01254   char old_bc = in->bc;
01255 
01256   if (in->bc == TRUE_PERIODIC || in->bc == APPROX_PERIODIC) {
01257     interface_filter(in, nx, ny);
01258     interface_redis(in, space);
01259     return;
01260   }
01261 
01262   xold = in->x[in->n-1];
01263   yold = in->y[in->n-1];
01264 
01265   in->x = (real *)realloc(in->x, nb * sizeof(real));
01266   in->y = (real *)realloc(in->y, nb * sizeof(real));
01267   in->t = (real *)realloc(in->t, nb * sizeof(real));
01268   in->spx = (polynom3 *)realloc(in->spx, (nb - 1) * sizeof(polynom3));
01269   in->spy = (polynom3 *)realloc(in->spy, (nb - 1) * sizeof(polynom3));
01270 
01271   for (i = 1; i <= in->n - 2; i++) {
01272           t = (in->t[i] + in->t[i+1])/2.;
01273           in->x[i] = splint(in->spx[i], t);
01274           in->y[i] = splint(in->spy[i], t);
01275   }
01276 
01277   for (i = in->n - 2; i <= 2*in->n - 5; i++){
01278           in->x[i] = in->x[i - in->n + 3];
01279           in->y[i] = in->y[i - in->n + 3];
01280   }
01281 
01282   for (i = 0; i <= in->n - 3; i++){
01283           in->x[i] = in->x[nb-1-i];
01284           in->y[i] = 4. - in->y[nb-1-i];
01285   }
01286 
01287 //  in->x[nb-1] = xold;
01288 //  in->y[nb-1] = yold + 2. * (real)ny - 4.;
01289 
01290   in->n = nb;
01291   in->bc = AXIBOTH;
01292 
01293   interface_splines(*in, nx, ny);
01294 
01295 #if 0
01296   
01297   n = polyroots(in->spy[nb-2], in->t[nb-2], in->t[nb-1], 
01298                 ti, 2.0, INTERPREC);
01299   if (n != 1) {
01300     FILE *fptr = fopen("aximarkers", "wt");
01301     interface_write_markers(*in, fptr);
01302     fclose(fptr);
01303     printf("ERROR: interface_axisymmetry(): n = %d\n", n);    
01304     exit(1);
01305   }
01306   xs = splint(in->spx[nb-2], ti[0]);
01307   ts = ti[0] - in->t[nb-1]; 
01308 
01309 #endif
01310   
01311   n = polyroots(in->spy[nold-3], in->t[nold-3], in->t[nold-2], 
01312                 ti, (real)ny, INTERPREC);
01313   if (n != 1) {
01314     FILE *fptr = fopen("aximarkers", "wt");
01315     interface_write_markers(*in, fptr);
01316     fclose(fptr);
01317     printf("ERROR: interface_axisymmetry(): n = %d\n", n);
01318     exit(1);
01319   }
01320   xe = splint(in->spx[nold-3], ti[0]);
01321   te = ti[0];
01322 
01323 /*  n = polyroots(in->spy[2*nold-2], in->t[2*nold-2], in->t[2*nold-1],
01324                   ti, 2.*(real)ny-2., INTERPREC);
01325   if (n != 1) {
01326           FILE *fptr = fopen("aximarkers", "wt");
01327           interface_write_markers(*in, fptr);
01328           fclose(fptr);
01329           printf("ERROR: interface_axisymmetry(): n = %d\n", n);
01330           exit(1);
01331   }
01332   xs = splint(in->spx[2*nold-2], ti[0]);
01333   ts = ti[0];
01334 */
01335 
01336 /*  dl = te / (real)(nold-1); 
01337   if (dl >= 1.0)
01338     printf("WARNING interface_redis(): dl=%g\n", dl);
01339 
01340   in->x = (real *)realloc(in->x, nold * sizeof(real));
01341   in->y = (real *)realloc(in->y, nold * sizeof(real));
01342 
01343   l = te + dl;
01344   k = 0;
01345 
01346   for (i = 1; i <= nold - 2; i++, l += dl) { 
01347 /* find the next interval [j;j+1] such as t[j] <= l <= t[j+1] 
01348     while(in->t[k+1] < l)
01349       k++;
01350     in->x[i] = splint(in->spx[k+nold-2], l);
01351     in->y[i] = splint(in->spy[k+nold-2], l);
01352   }
01353   
01354   in->x[0] = xs; in->y[0] = 1.9999;
01355   in->x[nold-1] = xe; in->y[nold-1] = (real)ny + 0.001;
01356   in->t = (real *)realloc(in->t, nold * sizeof(real));
01357   in->spx = (polynom3 *)realloc(in->spx, (nold - 1) * sizeof(polynom3));
01358   in->spy = (polynom3 *)realloc(in->spy, (nold - 1) * sizeof(polynom3));
01359 #ifdef FREE
01360   in->p = (real *)realloc(in->p, nold * sizeof(real));
01361 #endif
01362   in->n = nold;
01363   in->bc = old_bc;
01364 
01365 }
01366 cld*/

Generated on Wed Feb 19 22:26:50 2003 for Markers by doxygen1.2.18