Main Page   Data Structures   File List   Data Fields   Globals  

extra.c

Go to the documentation of this file.
00001 #include "utilf.h"
00002 #include "markers.h"
00003 #include "extra.h"
00004 #include "make_bc.h"
00005 #include "inout.h"
00006 
00007 #define DIST 2.5
00008 #define SQR2 1.4142136
00009 #define SYMMETRY(val) (val < 2.0 ? 4. - val : val)
00010 #define BC_YU(j,ny) (j <= 1 ? 3 - (j) : j >= ny ? 2*(ny) - (j) - 1 : j)
00011 #define BC_YV(j,ny) (j < 2 ? 4 - (j) : j > ny ? 2*(ny) - (j) : j)
00012 
00013 #define THETA1 0.463647609001   /* atan(0.5) */
00014 #define THETA2 0.785398163398   /* PI/4 */
00015 #define THETA3 1.10714871779    /* atan(2) */
00016 #define THETA4 1.5707963268     /* PI/2 */
00017 
00018 #define PREC 1e-3
00019 
00020 static int gauss(real A[7][7], real B[7], real C[7], int n);
00021 
00022 
00023 /* normal distance between a point and a segment. if the foot of the normal
00024    is not in the segment, the minimum distance between each of the end points
00025    is returned.
00026 */
00027 static real normal_dist(real xa, real ya, real xb, real yb, real x, real y,
00028                         int *which_end)
00029 {
00030   real ab, abac, ac, bc;
00031   ab = sqrt(sq(xb - xa) + sq(yb - ya));
00032   if (ab == 0.0) {
00033     *which_end = 1;
00034     return sqrt(sq(x - xa) + sq(y - ya));
00035   }
00036   abac = (xb - xa)*(x - xa) + (yb - ya)*(y - ya);
00037   if (abac < 0.0 || abac > sq(ab)) {
00038     ac = sqrt(sq(x - xa) + sq(y - ya));
00039     bc = sqrt(sq(x - xb) + sq(y - yb));
00040     if (ac < bc) { *which_end = 1; return ac; }
00041     *which_end = 2;
00042     return bc;
00043   }
00044   *which_end = 0;
00045   ac = sqrt(sq(x - xa) + sq(y - ya));
00046   bc = sqrt(sq(x - xb) + sq(y - yb));
00047   return fabs((xb - xa)*(y - ya) - (yb - ya)*(x - xa))/ab;
00048 }
00049 
00050 
00051 int closest_normal(real x, real y, interface in,
00052                    real *xmin, real *ymin, real *pmin, real *tmin,
00053                    real *xn, real *yn)
00054 {
00055   int i, span;
00056   real d, dmin, dl;
00057   int imin, found = 0, which;
00058 
00059   /* find the closest segment */
00060 #if 0
00061   dmin = normal_dist(in.x[0], in.y[0], in.x[1], in.y[1], x, y, &which);
00062   imin = 0;
00063   for (i = 1; i < in.n - 1; i++) {
00064     d = normal_dist(in.x[i], in.y[i], in.x[i+1], in.y[i+1], x, y, &which);
00065     if (d < dmin) { 
00066       dmin = d;
00067       if (which == 0 || which == 1) imin = i;
00068       else imin = i + 1;
00069     }
00070   }
00071 #else
00072   /* find the closest marker */
00073   dmin = sq(x - in.x[0]) + sq(y - in.y[0]); imin = 0;
00074   for (i = 1; i < in.n; i++) {
00075     d = sq(x - in.x[i]) + sq(y - in.y[i]);
00076     if (d < dmin) { dmin = d; imin = i; }
00077   }  
00078 #endif
00079 
00080   /* find the closest point on the interface */
00081   i = imin; span = 1;
00082   if (i < in.n - 1)
00083     found = distmin(in.spx[i], in.spy[i], x, y, tmin,
00084                     in.t[i], in.t[i+1], PREC);
00085   while (!found && (i + span < in.n - 1 || i - span >= 0)) {
00086     if (i + span < in.n - 1 &&
00087         (found = distmin(in.spx[i+span], in.spy[i+span], x, y, tmin,
00088                          in.t[i+span], in.t[i+span+1], PREC)))
00089       imin = i + span;
00090     else if (i - span >= 0 &&
00091              (found = distmin(in.spx[i-span], in.spy[i-span], x, y, tmin,
00092                               in.t[i-span], in.t[i-span+1], PREC)))
00093       imin = i - span;    
00094     span++;
00095   }
00096   if (!found) { 
00097     FILE *fptr = fopen("closest_splines", "wt");
00098     interface_write_splines(in, fptr, 1000);
00099     fclose(fptr);
00100     printf("&&&& %g %g %d %g\n", x, y, imin, dmin); 
00101       printf("%g %g\n%g %g\n%g %g\n", in.x[imin-1], in.y[imin-1],
00102              in.x[imin], in.y[imin],
00103              in.x[imin+1], in.y[imin+1]);
00104       return 0; 
00105   }
00106 
00107   *xn = - splint1(in.spy[imin], *tmin);
00108   *yn = splint1(in.spx[imin], *tmin);
00109 
00110   dl = sqrt(sq(*xn) + sq(*yn));
00111   *xn /= dl; *yn /= dl;
00112   *xmin = splint(in.spx[imin], *tmin);
00113   *ymin = splint(in.spy[imin], *tmin);
00114   *pmin = (*tmin - in.t[imin])/(in.t[imin+1] - in.t[imin])
00115     *(in.p[imin+1] - in.p[imin]) + in.p[imin];
00116 
00117   return 1;
00118 }
00119 
00120 
00121 #define NCLOSEST 3
00122 #define SQCLOSEST sq(2*NCLOSEST + 1)
00123  #define CLOSENESS(xu, yu, x, y, n1, n2)  (1.1*(sq(((xu) - (x))*(n1)) + \
00124     sq(((yu) - (y))*(n2))) + \
00125     2.1*sq((n2)*((xu) - (x)) - n1*((yu) - (y))))
00126 /* #define CLOSENESS(xu, yu, x, y, n1, n2)  MAX(sq(((xu) - (x))*(n1)) + \
00127    sq(((yu) - (y))*(n2)), \
00128    2.1*sq((n2)*((xu) - (x)) - n1*((yu) - (y)))) */
00129 
00130 int closest_u(real x, real y, real n1, real n2, real2D u, real2D ap,
00131               real *xu, real *yu, real *uu, 
00132               real *xmax, real *xmin, real *ymax, real *ymin,
00133               int nx, int ny)
00134 {
00135   int i, j, k, i1, j1, j2, n = 0;
00136   real xl, yl, ul, dl;
00137 
00138   *xmax = 0.0; *xmin = 2.*nx; *ymax = 0.0; *ymin = 2.*ny;
00139 
00140   i = x; j = (int) ((real)y - 0.5);
00141   for (i1 = i - NCLOSEST; i1 <= i + NCLOSEST; i1++)
00142     for (j1 = j - NCLOSEST; j1 <= j + NCLOSEST; j1++) {
00143       j2 = BC_YU(j1,ny);
00144       if (INU(i1,j2)) {
00145         xu[n] = i1; yu[n] = j1 + 0.5;
00146         *xmax = xu[n] > *xmax ? xu[n] : *xmax;
00147         *ymax = yu[n] > *ymax ? yu[n] : *ymax;
00148         *xmin = xu[n] < *xmin ? xu[n] : *xmin;
00149         *ymin = yu[n] < *ymin ? yu[n] : *ymin;
00150         uu[n++] = u[i1][j2];
00151       }
00152     }
00153 
00154   /* sort the points */
00155   for (k = 1; k < n; k++) {
00156     xl = xu[k]; yl = yu[k]; ul = uu[k];
00157     i = k - 1;
00158     dl = CLOSENESS(xl, yl, x, y, n1, n2);
00159     while (i >= 0 && CLOSENESS(xu[i], yu[i], x, y, n1, n2) > dl) {
00160       xu[i+1] = xu[i]; yu[i+1] = yu[i]; uu[i+1] = uu[i]; 
00161       i--;
00162     }
00163     xu[i+1] = xl; yu[i+1] = yl; uu[i+1] = ul;
00164   }
00165   return n;
00166 }
00167 
00168 
00169 int closest_v(real x, real y, real n1, real n2, real2D v, real2D ap,
00170               real *xv, real *yv, real *vv, 
00171               real *xmax, real *xmin, real *ymax, real *ymin,
00172               int nx, int ny)
00173 {
00174   int i, j, k, i1, j1, j2, n = 0;
00175   real xl, yl, vl, dl;
00176 
00177   *xmax = 0.0; *xmin = 2.*nx; *ymax = 0.0; *ymin = 2.*ny;
00178 
00179   i = (int)((real)x - 0.5); j = y;
00180   for (i1 = i - NCLOSEST; i1 <= i + NCLOSEST; i1++)
00181     for (j1 = j - NCLOSEST; j1 <= j + NCLOSEST; j1++) {
00182       j2 = BC_YV(j1,ny);
00183       if (INV(i1,j2)) {
00184         xv[n] = i1 + 0.5; yv[n] = j1;
00185         *xmax = xv[n] > *xmax ? xv[n] : *xmax;
00186         *ymax = yv[n] > *ymax ? yv[n] : *ymax;
00187         *xmin = xv[n] < *xmin ? xv[n] : *xmin;
00188         *ymin = yv[n] < *ymin ? yv[n] : *ymin;
00189         if (j1 == j2)
00190           vv[n++] = v[i1][j1];
00191         else
00192           vv[n++] = - v[i1][j2];
00193       }
00194     }
00195 
00196   /* sort the points */
00197   for (k = 1; k < n; k++) {
00198     xl = xv[k]; yl = yv[k]; vl = vv[k]; 
00199     i = k - 1;
00200     dl = CLOSENESS(xl, yl, x, y, n1, n2);
00201     while (i >= 0 && CLOSENESS(xv[i], yv[i], x, y, n1, n2) > dl) {
00202       xv[i+1] = xv[i]; yv[i+1] = yv[i]; vv[i+1] = vv[i]; 
00203       i--;
00204     }
00205     xv[i+1] = xl; yv[i+1] = yl; vv[i+1] = vl;
00206   }
00207   return n;
00208 }
00209 
00210 /* #define DEBUG_EXTRA */
00211 
00212 void extra_velocity_normals(real x, real y,
00213                             real n1, real n2, real xn, real yn,
00214                             real2D u, real2D v, real2D ap,
00215                             real *eu, real *ev,
00216                             real *dudx, real *dvdy, real *dudy, real *dvdx,
00217                             int nx, int ny)
00218 {
00219   int i, j, k, l, l1, kmin, kmax, lmin, lmax;
00220   int nsx = 0, nsy = 0, dx, dy;
00221   real xSx = 0., xSxx = 0., xSxy = 0., xSy = 0., xSyy = 0.;
00222   real ySx = 0., ySxx = 0., ySxy = 0., ySy = 0., ySyy = 0.;
00223   real xSu = 0., xSxu = 0., xSyu = 0.;
00224   real ySv = 0., ySxv = 0., ySyv = 0.;
00225   real sys[7][7] = {{0.,0.,0.,0.,0.,0.,0.},
00226                     {0.,0.,0.,0.,0.,0.,0.},
00227                     {0.,0.,0.,0.,0.,0.,0.},
00228                     {0.,0.,0.,0.,0.,0.,0.},
00229                     {0.,0.,0.,0.,0.,0.,0.},
00230                     {0.,0.,0.,0.,0.,0.,0.},
00231                     {0.,0.,0.,0.,0.,0.,0.}};
00232   real rhs[7] = {0.,0.,0.,0.,0.,0.,0.}, sol[7], dummy;
00233 #ifdef DEBUG_EXTRA  
00234 FILE *fptr1 = fopen("extra_upoints", "at");
00235 FILE *fptr2 = fopen("extra_vpoints", "at");
00236 FILE *fptr3 = fopen("extra_points", "at");
00237 FILE *fptr4 = fopen("extra_normals", "at");
00238 #endif
00239 
00240 #if 0
00241   /* find the velocity points using a 5x5 or 4x4 stencil */
00242   i = x + 0.5; j = y;
00243   dx = dy = 1;
00244 
00245   do {
00246     nsx = 0;
00247     xSx = xSxx = xSxy = xSy = xSyy = 0.;
00248     xSu = xSxu = xSyu = 0.;
00249     
00250     if (modf(x + 0.5, &dummy) == 0.0) { kmin = i - dx; kmax = i + dx - 1; }
00251     else { kmin = i - dx; kmax = i + dx; }
00252 
00253     if (modf(y, &dummy) == 0.0) { lmin = j - dy; lmax = j + dy - 1; }
00254     else { lmin = j - dy; lmax = j + dy; }
00255 
00256     for (k = kmin; k <= kmax; k++)
00257       for (l = lmin; l <= lmax; l++) {
00258         l1 = l < 2 ? 3 - l : l;
00259         if (INU(k,l1)) {
00260           xSx += (real)k; xSxx += sq((real)k);
00261           xSxy += (0.5 + (real)l)*(real)k;
00262           xSy += 0.5 + (real)l; xSyy += sq(0.5 + (real)l);
00263           xSu += u[k][l1]; xSxu += u[k][l1]*(real)k;
00264           xSyu += u[k][l1]*(0.5 + (real)l);
00265 #ifdef DEBUG_EXTRA
00266           fprintf(fptr1, "%g %g %g\n", (real)k, 0.5 + (real)l, u[k][l1]);
00267 #endif
00268           nsx++;
00269         }
00270       }
00271     dx++; dy++;
00272   } while((nsx <=  kmax - kmin + 1 || nsx <= lmax - lmin + 1) && dx <= 3);
00273   
00274   i = x; j = y + 0.5;
00275   dx = dy = 1;
00276   do {
00277     nsy = 0;
00278     ySx = ySxx = ySxy = ySy = ySyy = 0.;
00279     ySv = ySxv = ySyv = 0.;
00280 
00281     if (modf(x, &dummy) == 0.0) { kmin = i - dx; kmax = i + dx - 1; }
00282     else { kmin = i - dx; kmax = i + dx; }
00283 
00284     if (modf(y + 0.5, &dummy) == 0.0) { lmin = j - dy; lmax = j + dy - 1; }
00285     else { lmin = j - dy; lmax = j + dy; }
00286 
00287     for (k = kmin; k <= kmax; k++)
00288       for (l = lmin; l <= lmax; l++) {
00289         l1 = l < 2 ? 4 - l : l;
00290         if (INV(k,l1)) {
00291           ySx += 0.5 + (real)k; ySxx += sq(0.5 + (real)k); 
00292           ySxy += (0.5 + (real)k)*(real)l;
00293           ySy += (real)l; ySyy += sq((real)l);
00294           dummy = l1 == l ? v[k][l1] : - v[k][l1];
00295           ySv += dummy; ySxv += dummy*(0.5 + (real)k);
00296           ySyv += dummy*(real)l;
00297 #ifdef DEBUG_EXTRA
00298           fprintf(fptr2, "%g %g %g\n", 0.5+(real)k, (real)l, dummy);
00299 #endif
00300           nsy++;
00301         }
00302       }
00303     dx++; dy++;
00304   } while((nsy <= kmax - kmin + 1 || nsy <= lmax - lmin + 1) && dx <= 3);
00305 #else
00306   real xu[SQCLOSEST], yu[SQCLOSEST], uu[SQCLOSEST];
00307   real xv[SQCLOSEST], yv[SQCLOSEST], vv[SQCLOSEST];
00308   real xmaxu, xminu, ymaxu, yminu;
00309   real xmaxv, xminv, ymaxv, yminv;
00310   int n;
00311 
00312   nsx = nsy = 5;
00313   if ((n = closest_u(xn, yn, n1, n2, u, ap, xu, yu, uu, 
00314                      &xmaxu, &xminu, &ymaxu, &yminu, nx, ny)) < nsx) {
00315     printf("extra_velocity_normals(%g,%g): not enough u's\n", x, y);
00316     printf("xn: %g yn: %g n1: %g n2: %g\n", xn, yn, n1, n2);
00317     for (i = 0; i < n; i++)
00318       printf("  %g %g\n", xu[i], yu[i]);
00319     exit(1);
00320   }
00321   if ((n = closest_v(xn, yn, n1, n2, v, ap, xv, yv, vv, 
00322                      &xmaxv, &xminv, &ymaxv, &yminv, nx, ny)) < nsy) {
00323     printf("extra_velocity_normals(%g,%g): not enough v's\n", x, y);
00324     printf("xn: %g yn: %g n1: %g n2: %g\n", xn, yn, n1, n2);
00325     for (i = 0; i < n; i++)
00326       printf("  %g %g\n", xv[i], yv[i]);
00327     exit(1);
00328   }
00329 
00330   xSx = xSxx = xSxy = xSy = xSyy = 0.;
00331   xSu = xSxu = xSyu = 0.;
00332   for (i = 0; i < nsx; i++) {
00333     xSx += xu[i]; xSxx += sq(xu[i]);
00334     xSxy += xu[i]*yu[i];
00335     xSy += yu[i]; xSyy += sq(yu[i]);
00336     xSu += uu[i]; xSxu += uu[i]*xu[i];
00337     xSyu += uu[i]*yu[i];
00338 #ifdef DEBUG_EXTRA
00339     fprintf(fptr1, "%g %g %g\n", xu[i], yu[i], uu[i]);
00340 #endif
00341   }
00342 
00343   ySx = ySxx = ySxy = ySy = ySyy = 0.;
00344   ySv = ySxv = ySyv = 0.;
00345   for (i = 0; i < nsy; i++) {
00346     ySx += xv[i]; ySxx += sq(xv[i]); 
00347     ySxy += xv[i]*yv[i];
00348     ySy += yv[i]; ySyy += sq(yv[i]);
00349     ySv += vv[i]; ySxv += vv[i]*xv[i];
00350     ySyv += yv[i]*vv[i];
00351 #ifdef DEBUG_EXTRA
00352     fprintf(fptr2, "%g %g %g\n", xv[i], yv[i], vv[i]);
00353 #endif
00354   }
00355 #endif
00356 
00357   /* build the system of equations
00358      sys[i][0]*u0+sys[i][1]*v0+sys[i][2]*A11+sys[i][3]*A22+
00359      sys[i][4]*A12+sys[i][5]*A21+sys[i][6]*lambda=rhs[i] */
00360   sys[0][2] = n1*n2; sys[0][3] = -n1*n2;
00361   sys[0][4] = (sq(n2) - sq(n1))/2.0; sys[0][5] = sys[0][4];
00362   sys[1][0] = nsx; sys[1][2] = xSx; sys[1][4] = xSy;
00363   rhs[1] = xSu;
00364   sys[2][1] = nsy; sys[2][3] = ySy; sys[2][5] = ySx;
00365   rhs[2] = ySv;
00366   sys[3][0] = xSx; sys[3][2] = xSxx; sys[3][4] = xSxy;
00367   sys[3][6] = n1*n2/2.;
00368   rhs[3] = xSxu;
00369   sys[4][1] = ySy; sys[4][3] = ySyy; sys[4][5] = ySxy;
00370   sys[4][6] = - n1*n2/2.;
00371   rhs[4] = ySyv;
00372   sys[5][0] = xSy; sys[5][2] = xSxy; sys[5][4] = xSyy;
00373   sys[5][6] = (sq(n2) - sq(n1))/4.0;
00374   rhs[5] = xSyu;
00375   sys[6][1] = ySx; sys[6][3] = ySxy; sys[6][5] = ySxx;
00376   sys[6][6] = (sq(n2) - sq(n1))/4.0;
00377   rhs[6] = ySxv;
00378 
00379 #ifdef DEBUG_EXTRA
00380   fprintf(fptr1, "&\n\n");
00381   fprintf(fptr2, "&\n\n");
00382   fprintf(fptr3, "%g %g\n&\n\n", x, y);
00383   fprintf(fptr4, "%g %g\n%g %g\n&\n\n", xn, yn, xn + n1, yn + n2);
00384   fclose(fptr1); fclose(fptr2); fclose(fptr3); fclose(fptr4);
00385 #endif
00386 
00387   if (gauss(sys, rhs, sol, 7)) {
00388     printf("Error: extra_velocity(%g, %g): no solution\n", x, y);
00389     printf("       nsx: %d nsy: %d\n", nsx, nsy);
00390     for (i = 0; i < nsx; i++)
00391       printf("%g %g %g\n", xu[i], yu[i], uu[i]);
00392     printf("\n");
00393     for (i = 0; i < nsy; i++)
00394       printf("%g %g %g\n", xv[i], yv[i], vv[i]);
00395     printf("\n");
00396     for (i = 0; i < 7; i++) {
00397       for (j = 0; j < 7; j++)
00398         printf("%10g ", sys[i][j]);
00399       printf("\n");
00400     }
00401     exit(1);
00402   }
00403 
00404   *dudx = sol[2]; *dvdy = sol[3]; *dudy = sol[4]; *dvdx = sol[5];
00405   *eu = sol[0] + sol[2]*x + sol[4]*y;
00406   *ev = sol[1] + sol[5]*x + sol[3]*y;
00407 
00408   if (*eu != *eu || *ev != *ev) {
00409     printf("Error: extra_velocity(%g, %g): NaN\n", x, y);
00410     printf("       eu: %g ev: %g\n", *eu, *ev);
00411     printf("       nsx: %d nsy: %d\n", nsx, nsy);
00412     for (i = 0; i < nsx; i++)
00413       printf("%g %g %g\n", xu[i], yu[i], uu[i]);
00414     printf("\n");
00415     for (i = 0; i < nsy; i++)
00416       printf("%g %g %g\n", xv[i], yv[i], vv[i]);
00417     printf("\n");
00418     for (i = 0; i < 7; i++) {
00419       for (j = 0; j < 7; j++)
00420         printf("%10g ", sys[i][j]);
00421       printf("\n");
00422     }
00423     exit(1);
00424   }
00425 }
00426 
00427 
00428 void extra_velocity_normals2(real x, real y,
00429                              real n1, real n2, real xn, real yn,
00430                              real2D u, real2D v, 
00431                              real2D ap,
00432                              real *eu, real *ev,
00433                              real *dudx, real *dudy, real *dvdx, real *dvdy,
00434                              int nx, int ny)
00435 {
00436   int i, j, k, l, kmin, kmax, lmin, lmax;
00437   int nsx = 0, nsy = 0, dx, dy;
00438   real x1, y1;
00439   real xSx, xSxx, xSxy, xSy, xSyy, xSxxy, xSxyy, xSyyy, xSxxx,
00440     xSxxxy, xSxxyy, xSxyyy, xSyyyy, xSxxxx, xSu, xSxu, xSyu,
00441     xSxxu, xSyyu, xSxyu;
00442   real ySx, ySxx, ySxy, ySy, ySyy, ySxxy, ySxyy, ySyyy, ySxxx,
00443     ySxxxy, ySxxyy, ySxyyy, ySyyyy, ySxxxx, ySv, ySxv, ySyv,
00444     ySxxv, ySyyv, ySxyv;
00445   real sys[13][13] = {{0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.},
00446                       {0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.},
00447                       {0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.},
00448                       {0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.},
00449                       {0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.},
00450                       {0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.},
00451                       {0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.},
00452                       {0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.},
00453                       {0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.},
00454                       {0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.},
00455                       {0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.},
00456                       {0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.},
00457                       {0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.}};
00458   real rhs[13] = {0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.}, sol[13], dummy;
00459   real n1n2 = n1*n2, sqn = (sq(n2) - sq(n1))/2.;
00460   real xu[SQCLOSEST], yu[SQCLOSEST], uu[SQCLOSEST];
00461   real xv[SQCLOSEST], yv[SQCLOSEST], vv[SQCLOSEST];
00462   real xmaxu, ymaxu, xminu, yminu, xmaxv, ymaxv, xminv, yminv, det;
00463   /* #define DEBUG_EXTRA */
00464 #ifdef DEBUG_EXTRA  
00465   static int cas;
00466   FILE *fptr1, *fptr2, *fptr3, *fptr4;
00467   char s[256];
00468 
00469   sprintf(s, "extra_upoints%d", cas);
00470   fptr1 = fopen(s, "wt");
00471   sprintf(s, "extra_vpoints%d", cas);
00472   fptr2 = fopen(s, "wt");
00473   sprintf(s, "extra_u%d", cas);
00474   fptr3 = fopen(s, "wt");
00475   sprintf(s, "extra_v%d", cas++);
00476   fptr4 = fopen(s, "wt");
00477 #endif
00478 
00479   nsx = nsy = 12;
00480   if (closest_u(xn, yn, n1, n2, u, ap, xu, yu, uu, 
00481                 &xmaxu, &xminu, &ymaxu, &yminu, nx, ny) < nsx) {
00482     fprintf(stderr, "extra_velocity_normals2(%g,%g): not enough u's\n", x, y);
00483     exit(1);
00484   }
00485   if (closest_v(xn, yn, n1, n2, v, ap, xv, yv, vv, 
00486                 &xmaxv, &xminv, &ymaxv, &yminv, nx, ny) < nsy) {
00487     fprintf(stderr, "extra_velocity_normals2(%g,%g): not enough v's\n", x, y);
00488     exit(1);
00489   }
00490 
00491   xSx = xSxx = xSxy = xSy = xSyy = xSxxy = xSxyy = xSyyy = xSxxx =
00492     xSxxxy = xSxxyy = xSxyyy = xSyyyy = xSxxxx = xSu = xSxu = xSyu =
00493     xSxxu = xSyyu = xSxyu = 0.0;
00494   for (i = 0; i < nsx; i++) {
00495     x1 = xu[i]; y1 = yu[i];
00496     
00497     xSx += x1; xSxx += sq(x1);
00498     xSxy += x1*y1;
00499     xSy += y1; xSyy += sq(y1);
00500     
00501     xSxxy += sq(x1)*y1;
00502     xSxyy += x1*sq(y1);
00503     xSyyy += sq(y1)*y1;
00504     xSxxx += sq(x1)*x1;
00505     
00506     xSxxxy += sq(x1)*x1*y1;
00507     xSxxyy += sq(x1)*sq(y1);
00508     xSxyyy += x1*sq(y1)*y1;
00509     
00510     xSyyyy += sq(y1)*sq(y1);
00511     
00512     xSxxxx += sq(x1)*sq(x1);
00513     
00514     xSu += uu[i]; 
00515     xSxu += x1*uu[i];
00516     xSyu += y1*uu[i];
00517     xSxxu += sq(x1)*uu[i];
00518     xSyyu += sq(y1)*uu[i];
00519     xSxyu += x1*y1*uu[i];
00520   }
00521 
00522   ySx = ySxx = ySxy = ySy = ySyy = ySxxy = ySxyy = ySyyy = ySxxx =
00523     ySxxxy = ySxxyy = ySxyyy = ySyyyy = ySxxxx = ySv = ySxv = ySyv =
00524     ySxxv = ySyyv = ySxyv = 0.0;
00525   for (i = 0; i < nsy; i++) {
00526     x1 = xv[i]; y1 = yv[i];
00527     
00528     ySx += x1; ySxx += sq(x1);
00529     ySxy += x1*y1;
00530     ySy += y1; ySyy += sq(y1);
00531     
00532     ySxxy += sq(x1)*y1;
00533     ySxyy += x1*sq(y1);
00534     ySyyy += sq(y1)*y1;
00535     ySxxx += sq(x1)*x1;
00536     
00537     ySxxxy += sq(x1)*x1*y1;
00538     ySxxyy += sq(x1)*sq(y1);
00539     ySxyyy += x1*sq(y1)*y1;
00540     
00541     ySyyyy += sq(y1)*sq(y1);
00542     
00543     ySxxxx += sq(x1)*sq(x1);
00544     
00545     ySv += vv[i]; 
00546     ySxv += x1*vv[i];
00547     ySyv += y1*vv[i];
00548     ySxxv += sq(x1)*vv[i];
00549     ySyyv += sq(y1)*vv[i];
00550     ySxyv += x1*y1*vv[i];
00551   }
00552 
00553   sys[0][0] = 2.*n1n2*xn; sys[0][1] = 2.*sqn*yn; 
00554   sys[0][2] = n1n2*yn + sqn*xn; sys[0][3] = n1n2; sys[0][4] = sqn;
00555   sys[0][6] = 2.*sqn*xn; sys[0][7] = - 2.*n1n2*yn;
00556   sys[0][8] = sqn*yn - n1n2*xn; sys[0][9] = sqn; sys[0][10] = - n1n2;  
00557 
00558   sys[1][0] = xSxx; sys[1][1] = xSyy; sys[1][2] = xSxy;
00559   sys[1][3] = xSx; sys[1][4] = xSy; sys[1][5] = nsx;  
00560   rhs[1] = xSu;
00561   
00562   sys[2][0] = xSxxy; sys[2][1] = xSyyy; sys[2][2] = xSxyy;
00563   sys[2][3] = xSxy; sys[2][4] = xSyy; sys[2][5] = xSy;
00564   sys[2][12] = sqn/2.;
00565   rhs[2] = xSyu;
00566 
00567   sys[3][0] = xSxxx; sys[3][1] = xSxyy; sys[3][2] = xSxxy;
00568   sys[3][3] = xSxx; sys[3][4] = xSxy; sys[3][5] = xSx;
00569   sys[3][12] = n1n2/2.;
00570   rhs[3] = xSxu;
00571   
00572   sys[4][0] = xSxxxy; sys[4][1] = xSxyyy; sys[4][2] = xSxxyy;
00573   sys[4][3] = xSxxy; sys[4][4] = xSxyy; sys[4][5] = xSxy;
00574   sys[4][12] = (n1n2*yn + sqn*xn)/2.;
00575   rhs[4] = xSxyu;
00576 
00577   sys[5][0] = xSxxyy; sys[5][1] = xSyyyy; sys[5][2] = xSxyyy;
00578   sys[5][3] = xSxyy; sys[5][4] = xSyyy; sys[5][5] = xSyy;
00579   sys[5][12] = sqn*yn;
00580   rhs[5] = xSyyu;
00581 
00582   sys[6][0] = xSxxxx; sys[6][1] = xSxxyy; sys[6][2] = xSxxxy;
00583   sys[6][3] = xSxxx; sys[6][4] = xSxxy; sys[6][5] = xSxx;
00584   sys[6][12] = n1n2*xn;
00585   rhs[6] = xSxxu;
00586 
00587 
00588   sys[7][6] = ySxx; sys[7][7] = ySyy; sys[7][8] = ySxy;
00589   sys[7][9] = ySx; sys[7][10] = ySy; sys[7][11] = nsy;  
00590   rhs[7] = ySv;
00591   
00592   sys[8][6] = ySxxy; sys[8][7] = ySyyy; sys[8][8] = ySxyy;
00593   sys[8][9] = ySxy; sys[8][10] = ySyy; sys[8][11] = ySy;
00594   sys[8][12] = - n1n2/2.;
00595   rhs[8] = ySyv;
00596 
00597   sys[9][6] = ySxxx; sys[9][7] = ySxyy; sys[9][8] = ySxxy;
00598   sys[9][9] = ySxx; sys[9][10] = ySxy; sys[9][11] = ySx;
00599   sys[9][12] = sqn/2.;
00600   rhs[9] = ySxv;
00601   
00602   sys[10][6] = ySxxxy; sys[10][7] = ySxyyy; sys[10][8] = ySxxyy;
00603   sys[10][9] = ySxxy; sys[10][10] = ySxyy; sys[10][11] = ySxy;
00604   sys[10][12] = (- n1n2*xn + sqn*yn)/2.;
00605   rhs[10] = ySxyv;
00606 
00607   sys[11][6] = ySxxyy; sys[11][7] = ySyyyy; sys[11][8] = ySxyyy;
00608   sys[11][9] = ySxyy; sys[11][10] = ySyyy; sys[11][11] = ySyy;
00609   sys[11][12] = - n1n2*yn;
00610   rhs[11] = ySyyv;
00611 
00612   sys[12][6] = ySxxxx; sys[12][7] = ySxxyy; sys[12][8] = ySxxxy;
00613   sys[12][9] = ySxxx; sys[12][10] = ySxxy; sys[12][11] = ySxx;
00614   sys[12][12] = sqn*xn;
00615   rhs[12] = ySxxv;
00616 
00617 #ifdef DEBUG_EXTRA
00618   for (i = 0; i < nsx; i++)
00619     fprintf(fptr1, "%g %g %f\n", xu[i], yu[i], uu[i]);
00620   for (i = 0; i < nsy; i++)
00621     fprintf(fptr2, "%g %g %f\n", xv[i], yv[i], vv[i]);
00622   fclose(fptr1); fclose(fptr2);
00623 #endif
00624 
00625   if (gauss13(sys, rhs, sol, &det, 13)) {
00626     printf("Error: extra_velocity2(%g, %g): no solution\n", x, y);
00627     printf("       nsx: %d nsy: %d\n", nsx, nsy);
00628     for (i = 0; i < 13; i++) {
00629       for (j = 0; j < 13; j++)
00630         printf("%5g ", sys[i][j]);
00631       printf("\n");
00632     }
00633     exit(1);
00634   }
00635 
00636 #ifdef DEBUG_EXTRA
00637   for (x1 = xminu; x1 <= xmaxu; x1 += 1.0) {
00638     for (y1 = yminu; y1 <= ymaxu; y1 += 1.0)
00639       fprintf(fptr3, "%g %g %g\n", x1, y1, 
00640               sol[0]*sq(x1) + sol[1]*sq(y1) + sol[2]*x1*y1 + 
00641               sol[3]*x1 + sol[4]*y1 + sol[5]);
00642     fprintf(fptr3, "\n");
00643   }
00644   fclose(fptr3);
00645   for (x1 = xminv; x1 <= xmaxv; x1 += 1.0) {
00646     for (y1 = yminv; y1 <= ymaxv; y1 += 1.0)
00647       fprintf(fptr4, "%g %g %g\n", x1, y1, 
00648               sol[6]*sq(x1) + sol[7]*sq(y1) + sol[8]*x1*y1 + 
00649               sol[9]*x1 + sol[10]*y1 + sol[11]);
00650     fprintf(fptr4, "\n");
00651   }
00652   fclose(fptr4);
00653   x1 = 0.0;
00654   for (i = 0; i < nsx; i++) {
00655     y1 = sol[0]*sq(xu[i]) + sol[1]*sq(yu[i]) + sol[2]*xu[i]*yu[i] + 
00656       sol[3]*xu[i] + sol[4]*yu[i] + sol[5];
00657     x1 += sq(y1 - uu[i]);
00658   }
00659   for (i = 0; i < nsy; i++) {
00660     y1 = sol[6]*sq(xv[i]) + sol[7]*sq(yv[i]) + sol[8]*xv[i]*yv[i] + 
00661       sol[9]*xv[i] + sol[10]*yv[i] + sol[11];
00662     x1 += sq(y1 - vv[i]);
00663   }
00664   printf("%g %g %g\n", x, y, x1);
00665 #endif
00666 
00667   *eu = sol[0]*sq(x) + sol[1]*sq(y) + sol[2]*x*y + 
00668     sol[3]*x + sol[4]*y + sol[5];
00669   *ev = sol[6]*sq(x) + sol[7]*sq(y) + sol[8]*x*y + 
00670     sol[9]*x + sol[10]*y + sol[11];
00671   *dudx = 2.*sol[0]*x + sol[2]*y + sol[3];
00672   *dudy = 2.*sol[1]*y + sol[2]*x + sol[4];
00673   *dvdx = 2.*sol[6]*x + sol[8]*y + sol[9];
00674   *dvdy = 2.*sol[7]*y + sol[8]*x + sol[10];
00675 }
00676 
00677 
00678 void extra_velocity(real x, real y,
00679                     real2D u, real2D v, real2D ap,
00680                     interface in,
00681                     real *eu, real *ev,
00682                     int nx, int ny)
00683 {
00684   real n1, n2;
00685   real a11, a22, a12, a21;
00686   real xmin, ymin, pmin, tmin;
00687   if (!closest_normal(x, y, in, &xmin, &ymin, &pmin, &tmin, &n1, &n2)) {
00688     fprintf(stderr, "extra_velocity(%g, %g): no closest_normal\n", x, y);
00689     exit(1);
00690   }
00691 #ifdef EXTRA_LINEAR
00692   extra_velocity_normals(x, y, n1, n2, xmin, ymin,
00693                          u, v, ap, 
00694                          eu, ev, &a11, &a22, &a12, &a21,
00695                          nx, ny);
00696 #else
00697   extra_velocity_normals2(x, y, n1, n2, xmin, ymin,
00698                           u, v, ap, 
00699                           eu, ev, &a11, &a22, &a12, &a21,
00700                           nx, ny);
00701 #endif
00702 }
00703 
00704 
00705 real kappa_normals(polynom3 px, polynom3 py, real t, real *nx, real *ny)
00706 {
00707   real xp, yp, y, dl, kappa;
00708 
00709   xp = splint1(px, t);
00710   yp = splint1(py, t);
00711   dl = sqrt(sq(xp) + sq(yp));
00712   kappa = (xp*splint2(py, t) - yp*splint2(px, t))/(sq(dl)*dl);
00713   /* axisymmetric term */
00714   y = splint(py, t) - 2.0;
00715   if (fabs(y) < 1e-2) /* second order approximation near the axis */
00716     kappa -= splint2(px, t)/splint1(py, t)/dl;
00717   else
00718     kappa -= xp/y/dl;
00719   *nx = - yp/dl;
00720   *ny = xp/dl;
00721   return kappa;
00722 }
00723 
00724 
00725 real avg_kappa_normals(polynom3 px, polynom3 py, real t1, real t2,
00726                        real *nx, real *ny)
00727 {
00728   static real coef[7] = {1., 3., 3., 2., 3., 3., 1.}; 
00729   int i;
00730   real xp, yp, y, h = (t2 - t1)/6., t, kappasum = 0.0, lsum = 0.0, dl2;
00731 
00732   for (i = 0; i < 7; i++) {
00733     t = t1 + h*i;
00734     xp = splint1(px, t);
00735     yp = splint1(py, t);
00736     dl2 = sq(xp) + sq(yp);
00737     kappasum += coef[i]*((xp*splint2(py, t) - yp*splint2(px, t))/dl2);
00738     /* axisymmetric term */
00739     y = splint(py, t) - 2.0;
00740     if (fabs(y) < 1e-2) /* second order approximation near the axis */
00741       kappasum -= coef[i]*splint2(px, t)/splint1(py, t);
00742     else
00743       kappasum -= coef[i]*xp/y;
00744     lsum += coef[i]*sqrt(dl2);
00745   }
00746   *nx = 8.*(splint(py, t2) - splint(py, t1))/(3.*h*lsum);
00747   *ny = - 8.*(splint(px, t2) - splint(px, t1))/(3.*h*lsum);
00748   return kappasum/lsum;
00749 }
00750 
00751 
00752 /* -------------------------------------------------------------------------
00753                 Resoud un systeme d'equations lineaires
00754                 du type A * C = B par la methode du pivot de Gauss
00755    ------------------------------------------------------------------------- */
00756 #define GAUSSTOL 1.e-10
00757 
00758 static int gauss(real A[7][7], real B[7], real C[7], int n)
00759 {
00760   int i, j, k, i1;
00761   real max, temp;
00762   
00763   for (j = 0; j <= n - 2; j++) {
00764     i1 = j;
00765     max = fabs(A[j][j]);
00766     for (i = j + 1; i < n; i++) {
00767       if (fabs(A[i][j]) >= max) {
00768         i1 = i;
00769         max = fabs(A[i][j]);
00770       }
00771     }
00772     for (k = j; k < n; k++) {
00773       max = A[j][k]; A[j][k] = A[i1][k]; A[i1][k] = max;
00774     }
00775     max = B[j]; B[j] = B[i1]; B[i1] = max;
00776     for (i = j + 1; i < n; i++) {
00777       if (fabs(A[j][j]) < GAUSSTOL)
00778         return 1;
00779       else
00780         temp = A[i][j] / A[j][j];
00781       for (k = j; k < n; k++)
00782         A[i][k] -= temp * A[j][k];
00783       B[i] -= temp * B[j];
00784     }
00785   }
00786 
00787   if (fabs(A[n-1][n-1]) < GAUSSTOL)
00788     return 1;
00789   C[n - 1] = B[n - 1] / A[n - 1][n - 1];
00790   for (i = n - 2; i >= 0; i--) {
00791     C[i] = B[i];
00792     for (k = i + 1; k < n; k++)
00793       C[i] -= A[i][k] * C[k];
00794     if (fabs(A[i][i]) < GAUSSTOL)
00795       return 1;
00796     C[i] /= A[i][i];
00797   }
00798   return 0;
00799 }
00800 
00801 
00802 int gauss13(real A[13][13], real B[13], real C[13], real *d, int n)
00803 {
00804   int i, j, k, i1;
00805   real max, temp, det = 1.0;
00806   
00807   for (j = 0; j <= n - 2; j++) {
00808     i1 = j;
00809     max = fabs(A[j][j]);
00810     for (i = j + 1; i < n; i++) {
00811       if (fabs(A[i][j]) >= max) {
00812         i1 = i;
00813         max = fabs(A[i][j]);
00814       }
00815     }
00816     for (k = j; k < n; k++) {
00817       max = A[j][k]; A[j][k] = A[i1][k]; A[i1][k] = max;
00818     }
00819     max = B[j]; B[j] = B[i1]; B[i1] = max;
00820     for (i = j + 1; i < n; i++) {
00821       if (fabs(A[j][j]) < 1e-10)
00822         return 1;
00823       temp = A[i][j] / A[j][j];
00824       for (k = j; k < n; k++)
00825         A[i][k] -= temp * A[j][k];
00826       B[i] -= temp * B[j];
00827     }
00828   }
00829 
00830   for (i = 0; i < n; i++)
00831     det *= A[i][i];
00832   *d = det;
00833   if (fabs(det) < 1.e-10)
00834     return 1;
00835 
00836   if (fabs(A[n-1][n-1]) < 1.e-10)
00837     return 1;
00838   C[n - 1] = B[n - 1] / A[n - 1][n - 1];
00839   for (i = n - 2; i >= 0; i--) {
00840     C[i] = B[i];
00841     for (k = i + 1; k < n; k++)
00842       C[i] -= A[i][k] * C[k];
00843     if (fabs(A[i][i]) < 1.e-10)
00844       return 1;
00845     C[i] /= A[i][i];
00846   }
00847   return 0;
00848 }
00849 
00850 
00851 int gauss2(real **A, real *B, real *C, int n)
00852 {
00853   int i, j, k, i1;
00854   real max, temp;
00855   
00856   for (j = 0; j <= n - 2; j++) {
00857     i1 = j;
00858     max = fabs(A[j][j]);
00859     for (i = j + 1; i < n; i++) {
00860       if (fabs(A[i][j]) >= max) {
00861         i1 = i;
00862         max = fabs(A[i][j]);
00863       }
00864     }
00865     for (k = j; k < n; k++) {
00866       max = A[j][k]; A[j][k] = A[i1][k]; A[i1][k] = max;
00867     }
00868     max = B[j]; B[j] = B[i1]; B[i1] = max;
00869     for (i = j + 1; i < n; i++) {
00870       if (A[j][j] == 0.)
00871         return 1;
00872       else
00873         temp = A[i][j] / A[j][j];
00874       for (k = j; k < n; k++)
00875         A[i][k] -= temp * A[j][k];
00876       B[i] -= temp * B[j];
00877     }
00878   }
00879   if (A[n - 1][n - 1] == 0.)
00880     return 1;
00881   else
00882     C[n - 1] = B[n - 1] / A[n - 1][n - 1];
00883   for (i = n - 2; i >= 0; i--) {
00884     C[i] = B[i];
00885     for (k = i + 1; k < n; k++)
00886       C[i] -= A[i][k] * C[k];
00887     C[i] /= A[i][i];
00888   }
00889   return 0;
00890 }
00891 
00892 

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